Roll DEPS for PDFium to 19ae17578f99621100a26dac3e2c7c3dbf7c7cd1
[chromium-blink-merge.git] / tools / gn / target_unittest.cc
blob020d43226763d0d02b795e574b82d96f87e8c024
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "testing/gtest/include/gtest/gtest.h"
6 #include "tools/gn/build_settings.h"
7 #include "tools/gn/config.h"
8 #include "tools/gn/settings.h"
9 #include "tools/gn/target.h"
10 #include "tools/gn/test_with_scope.h"
11 #include "tools/gn/toolchain.h"
13 // Tests that lib[_dir]s are inherited across deps boundaries for static
14 // libraries but not executables.
15 TEST(Target, LibInheritance) {
16 TestWithScope setup;
17 Err err;
19 const std::string lib("foo");
20 const SourceDir libdir("/foo_dir/");
22 // Leaf target with ldflags set.
23 Target z(setup.settings(), Label(SourceDir("//foo/"), "z"));
24 z.set_output_type(Target::STATIC_LIBRARY);
25 z.config_values().libs().push_back(lib);
26 z.config_values().lib_dirs().push_back(libdir);
27 z.visibility().SetPublic();
28 z.SetToolchain(setup.toolchain());
29 ASSERT_TRUE(z.OnResolved(&err));
31 // All lib[_dir]s should be set when target is resolved.
32 ASSERT_EQ(1u, z.all_libs().size());
33 EXPECT_EQ(lib, z.all_libs()[0]);
34 ASSERT_EQ(1u, z.all_lib_dirs().size());
35 EXPECT_EQ(libdir, z.all_lib_dirs()[0]);
37 // Shared library target should inherit the libs from the static library
38 // and its own. Its own flag should be before the inherited one.
39 const std::string second_lib("bar");
40 const SourceDir second_libdir("/bar_dir/");
41 Target shared(setup.settings(), Label(SourceDir("//foo/"), "shared"));
42 shared.set_output_type(Target::SHARED_LIBRARY);
43 shared.config_values().libs().push_back(second_lib);
44 shared.config_values().lib_dirs().push_back(second_libdir);
45 shared.private_deps().push_back(LabelTargetPair(&z));
46 shared.visibility().SetPublic();
47 shared.SetToolchain(setup.toolchain());
48 ASSERT_TRUE(shared.OnResolved(&err));
50 ASSERT_EQ(2u, shared.all_libs().size());
51 EXPECT_EQ(second_lib, shared.all_libs()[0]);
52 EXPECT_EQ(lib, shared.all_libs()[1]);
53 ASSERT_EQ(2u, shared.all_lib_dirs().size());
54 EXPECT_EQ(second_libdir, shared.all_lib_dirs()[0]);
55 EXPECT_EQ(libdir, shared.all_lib_dirs()[1]);
57 // Executable target shouldn't get either by depending on shared.
58 Target exec(setup.settings(), Label(SourceDir("//foo/"), "exec"));
59 exec.set_output_type(Target::EXECUTABLE);
60 exec.private_deps().push_back(LabelTargetPair(&shared));
61 exec.SetToolchain(setup.toolchain());
62 ASSERT_TRUE(exec.OnResolved(&err));
63 EXPECT_EQ(0u, exec.all_libs().size());
64 EXPECT_EQ(0u, exec.all_lib_dirs().size());
67 // Test all_dependent_configs, public_config inheritance, and
68 // forward_dependent_configs_from
69 TEST(Target, DependentConfigs) {
70 TestWithScope setup;
71 Err err;
73 // Set up a dependency chain of a -> b -> c
74 Target a(setup.settings(), Label(SourceDir("//foo/"), "a"));
75 a.set_output_type(Target::EXECUTABLE);
76 a.visibility().SetPublic();
77 a.SetToolchain(setup.toolchain());
78 Target b(setup.settings(), Label(SourceDir("//foo/"), "b"));
79 b.set_output_type(Target::STATIC_LIBRARY);
80 b.visibility().SetPublic();
81 b.SetToolchain(setup.toolchain());
82 Target c(setup.settings(), Label(SourceDir("//foo/"), "c"));
83 c.set_output_type(Target::STATIC_LIBRARY);
84 c.visibility().SetPublic();
85 c.SetToolchain(setup.toolchain());
86 a.private_deps().push_back(LabelTargetPair(&b));
87 b.private_deps().push_back(LabelTargetPair(&c));
89 // Normal non-inherited config.
90 Config config(setup.settings(), Label(SourceDir("//foo/"), "config"));
91 c.configs().push_back(LabelConfigPair(&config));
93 // All dependent config.
94 Config all(setup.settings(), Label(SourceDir("//foo/"), "all"));
95 c.all_dependent_configs().push_back(LabelConfigPair(&all));
97 // Direct dependent config.
98 Config direct(setup.settings(), Label(SourceDir("//foo/"), "direct"));
99 c.public_configs().push_back(LabelConfigPair(&direct));
101 ASSERT_TRUE(c.OnResolved(&err));
102 ASSERT_TRUE(b.OnResolved(&err));
103 ASSERT_TRUE(a.OnResolved(&err));
105 // B should have gotten both dependent configs from C.
106 ASSERT_EQ(2u, b.configs().size());
107 EXPECT_EQ(&all, b.configs()[0].ptr);
108 EXPECT_EQ(&direct, b.configs()[1].ptr);
109 ASSERT_EQ(1u, b.all_dependent_configs().size());
110 EXPECT_EQ(&all, b.all_dependent_configs()[0].ptr);
112 // A should have just gotten the "all" dependent config from C.
113 ASSERT_EQ(1u, a.configs().size());
114 EXPECT_EQ(&all, a.configs()[0].ptr);
115 EXPECT_EQ(&all, a.all_dependent_configs()[0].ptr);
117 // Making an an alternate A and B with B forwarding the direct dependents.
118 Target a_fwd(setup.settings(), Label(SourceDir("//foo/"), "a_fwd"));
119 a_fwd.set_output_type(Target::EXECUTABLE);
120 a_fwd.visibility().SetPublic();
121 a_fwd.SetToolchain(setup.toolchain());
122 Target b_fwd(setup.settings(), Label(SourceDir("//foo/"), "b_fwd"));
123 b_fwd.set_output_type(Target::STATIC_LIBRARY);
124 b_fwd.SetToolchain(setup.toolchain());
125 b_fwd.visibility().SetPublic();
126 a_fwd.private_deps().push_back(LabelTargetPair(&b_fwd));
127 b_fwd.private_deps().push_back(LabelTargetPair(&c));
128 b_fwd.forward_dependent_configs().push_back(LabelTargetPair(&c));
130 ASSERT_TRUE(b_fwd.OnResolved(&err));
131 ASSERT_TRUE(a_fwd.OnResolved(&err));
133 // A_fwd should now have both configs.
134 ASSERT_EQ(2u, a_fwd.configs().size());
135 EXPECT_EQ(&all, a_fwd.configs()[0].ptr);
136 EXPECT_EQ(&direct, a_fwd.configs()[1].ptr);
137 ASSERT_EQ(1u, a_fwd.all_dependent_configs().size());
138 EXPECT_EQ(&all, a_fwd.all_dependent_configs()[0].ptr);
141 TEST(Target, InheritLibs) {
142 TestWithScope setup;
143 Err err;
145 // Create a dependency chain:
146 // A (executable) -> B (shared lib) -> C (static lib) -> D (source set)
147 Target a(setup.settings(), Label(SourceDir("//foo/"), "a"));
148 a.set_output_type(Target::EXECUTABLE);
149 a.visibility().SetPublic();
150 a.SetToolchain(setup.toolchain());
151 Target b(setup.settings(), Label(SourceDir("//foo/"), "b"));
152 b.set_output_type(Target::SHARED_LIBRARY);
153 b.visibility().SetPublic();
154 b.SetToolchain(setup.toolchain());
155 Target c(setup.settings(), Label(SourceDir("//foo/"), "c"));
156 c.set_output_type(Target::STATIC_LIBRARY);
157 c.visibility().SetPublic();
158 c.SetToolchain(setup.toolchain());
159 Target d(setup.settings(), Label(SourceDir("//foo/"), "d"));
160 d.set_output_type(Target::SOURCE_SET);
161 d.visibility().SetPublic();
162 d.SetToolchain(setup.toolchain());
163 a.private_deps().push_back(LabelTargetPair(&b));
164 b.private_deps().push_back(LabelTargetPair(&c));
165 c.private_deps().push_back(LabelTargetPair(&d));
167 ASSERT_TRUE(d.OnResolved(&err));
168 ASSERT_TRUE(c.OnResolved(&err));
169 ASSERT_TRUE(b.OnResolved(&err));
170 ASSERT_TRUE(a.OnResolved(&err));
172 // C should have D in its inherited libs.
173 std::vector<const Target*> c_inherited = c.inherited_libraries().GetOrdered();
174 ASSERT_EQ(1u, c_inherited.size());
175 EXPECT_EQ(&d, c_inherited[0]);
177 // B should have C and D in its inherited libs.
178 std::vector<const Target*> b_inherited = b.inherited_libraries().GetOrdered();
179 ASSERT_EQ(2u, b_inherited.size());
180 EXPECT_EQ(&c, b_inherited[0]);
181 EXPECT_EQ(&d, b_inherited[1]);
183 // A should have B in its inherited libs, but not any others (the shared
184 // library will include the static library and source set).
185 std::vector<const Target*> a_inherited = a.inherited_libraries().GetOrdered();
186 ASSERT_EQ(1u, a_inherited.size());
187 EXPECT_EQ(&b, a_inherited[0]);
190 TEST(Target, InheritCompleteStaticLib) {
191 TestWithScope setup;
192 Err err;
194 // Create a dependency chain:
195 // A (executable) -> B (complete static lib) -> C (source set)
196 Target a(setup.settings(), Label(SourceDir("//foo/"), "a"));
197 a.set_output_type(Target::EXECUTABLE);
198 a.visibility().SetPublic();
199 a.SetToolchain(setup.toolchain());
200 Target b(setup.settings(), Label(SourceDir("//foo/"), "b"));
201 b.set_output_type(Target::STATIC_LIBRARY);
202 b.visibility().SetPublic();
203 b.set_complete_static_lib(true);
204 b.SetToolchain(setup.toolchain());
205 Target c(setup.settings(), Label(SourceDir("//foo/"), "c"));
206 c.set_output_type(Target::SOURCE_SET);
207 c.visibility().SetPublic();
208 c.SetToolchain(setup.toolchain());
209 a.public_deps().push_back(LabelTargetPair(&b));
210 b.public_deps().push_back(LabelTargetPair(&c));
212 ASSERT_TRUE(c.OnResolved(&err));
213 ASSERT_TRUE(b.OnResolved(&err));
214 ASSERT_TRUE(a.OnResolved(&err));
216 // B should have C in its inherited libs.
217 std::vector<const Target*> b_inherited = b.inherited_libraries().GetOrdered();
218 ASSERT_EQ(1u, b_inherited.size());
219 EXPECT_EQ(&c, b_inherited[0]);
221 // A should have B in its inherited libs, but not any others (the complete
222 // static library will include the source set).
223 std::vector<const Target*> a_inherited = a.inherited_libraries().GetOrdered();
224 EXPECT_EQ(1u, a_inherited.size());
225 EXPECT_EQ(&b, a_inherited[0]);
228 TEST(Target, InheritCompleteStaticLibNoDirectStaticLibDeps) {
229 TestWithScope setup;
230 Err err;
232 // Create a dependency chain:
233 // A (complete static lib) -> B (static lib)
234 Target a(setup.settings(), Label(SourceDir("//foo/"), "a"));
235 a.set_output_type(Target::STATIC_LIBRARY);
236 a.visibility().SetPublic();
237 a.set_complete_static_lib(true);
238 a.SetToolchain(setup.toolchain());
239 Target b(setup.settings(), Label(SourceDir("//foo/"), "b"));
240 b.set_output_type(Target::STATIC_LIBRARY);
241 b.visibility().SetPublic();
242 b.SetToolchain(setup.toolchain());
244 a.public_deps().push_back(LabelTargetPair(&b));
245 ASSERT_TRUE(b.OnResolved(&err));
246 ASSERT_FALSE(a.OnResolved(&err));
249 TEST(Target, InheritCompleteStaticLibNoIheritedStaticLibDeps) {
250 TestWithScope setup;
251 Err err;
253 // Create a dependency chain:
254 // A (complete static lib) -> B (source set) -> C (static lib)
255 Target a(setup.settings(), Label(SourceDir("//foo/"), "a"));
256 a.set_output_type(Target::STATIC_LIBRARY);
257 a.visibility().SetPublic();
258 a.set_complete_static_lib(true);
259 a.SetToolchain(setup.toolchain());
260 Target b(setup.settings(), Label(SourceDir("//foo/"), "b"));
261 b.set_output_type(Target::SOURCE_SET);
262 b.visibility().SetPublic();
263 b.SetToolchain(setup.toolchain());
264 Target c(setup.settings(), Label(SourceDir("//foo/"), "c"));
265 c.set_output_type(Target::STATIC_LIBRARY);
266 c.visibility().SetPublic();
267 c.SetToolchain(setup.toolchain());
269 a.public_deps().push_back(LabelTargetPair(&b));
270 b.public_deps().push_back(LabelTargetPair(&c));
272 ASSERT_TRUE(c.OnResolved(&err));
273 ASSERT_TRUE(b.OnResolved(&err));
274 ASSERT_FALSE(a.OnResolved(&err));
277 TEST(Target, GetComputedOutputName) {
278 TestWithScope setup;
279 Err err;
281 // Basic target with no prefix (executable type tool in the TestWithScope has
282 // no prefix) or output name.
283 Target basic(setup.settings(), Label(SourceDir("//foo/"), "bar"));
284 basic.set_output_type(Target::EXECUTABLE);
285 basic.SetToolchain(setup.toolchain());
286 ASSERT_TRUE(basic.OnResolved(&err));
287 EXPECT_EQ("bar", basic.GetComputedOutputName(false));
288 EXPECT_EQ("bar", basic.GetComputedOutputName(true));
290 // Target with no prefix but an output name.
291 Target with_name(setup.settings(), Label(SourceDir("//foo/"), "bar"));
292 with_name.set_output_type(Target::EXECUTABLE);
293 with_name.set_output_name("myoutput");
294 with_name.SetToolchain(setup.toolchain());
295 ASSERT_TRUE(with_name.OnResolved(&err));
296 EXPECT_EQ("myoutput", with_name.GetComputedOutputName(false));
297 EXPECT_EQ("myoutput", with_name.GetComputedOutputName(true));
299 // Target with a "lib" prefix (the static library tool in the TestWithScope
300 // should specify a "lib" output prefix).
301 Target with_prefix(setup.settings(), Label(SourceDir("//foo/"), "bar"));
302 with_prefix.set_output_type(Target::STATIC_LIBRARY);
303 with_prefix.SetToolchain(setup.toolchain());
304 ASSERT_TRUE(with_prefix.OnResolved(&err));
305 EXPECT_EQ("bar", with_prefix.GetComputedOutputName(false));
306 EXPECT_EQ("libbar", with_prefix.GetComputedOutputName(true));
308 // Target with a "lib" prefix that already has it applied. The prefix should
309 // not duplicate something already in the target name.
310 Target dup_prefix(setup.settings(), Label(SourceDir("//foo/"), "bar"));
311 dup_prefix.set_output_type(Target::STATIC_LIBRARY);
312 dup_prefix.set_output_name("libbar");
313 dup_prefix.SetToolchain(setup.toolchain());
314 ASSERT_TRUE(dup_prefix.OnResolved(&err));
315 EXPECT_EQ("libbar", dup_prefix.GetComputedOutputName(false));
316 EXPECT_EQ("libbar", dup_prefix.GetComputedOutputName(true));
319 // Test visibility failure case.
320 TEST(Target, VisibilityFails) {
321 TestWithScope setup;
322 Err err;
324 Target b(setup.settings(), Label(SourceDir("//private/"), "b"));
325 b.set_output_type(Target::STATIC_LIBRARY);
326 b.SetToolchain(setup.toolchain());
327 b.visibility().SetPrivate(b.label().dir());
328 ASSERT_TRUE(b.OnResolved(&err));
330 // Make a target depending on "b". The dependency must have an origin to mark
331 // it as user-set so we check visibility. This check should fail.
332 Target a(setup.settings(), Label(SourceDir("//app/"), "a"));
333 a.set_output_type(Target::EXECUTABLE);
334 a.private_deps().push_back(LabelTargetPair(&b));
335 IdentifierNode origin; // Dummy origin.
336 a.private_deps()[0].origin = &origin;
337 a.SetToolchain(setup.toolchain());
338 ASSERT_FALSE(a.OnResolved(&err));
341 // Test visibility with a single data_dep.
342 TEST(Target, VisibilityDatadeps) {
343 TestWithScope setup;
344 Err err;
346 Target b(setup.settings(), Label(SourceDir("//public/"), "b"));
347 b.set_output_type(Target::STATIC_LIBRARY);
348 b.SetToolchain(setup.toolchain());
349 b.visibility().SetPublic();
350 ASSERT_TRUE(b.OnResolved(&err));
352 // Make a target depending on "b". The dependency must have an origin to mark
353 // it as user-set so we check visibility. This check should fail.
354 Target a(setup.settings(), Label(SourceDir("//app/"), "a"));
355 a.set_output_type(Target::EXECUTABLE);
356 a.data_deps().push_back(LabelTargetPair(&b));
357 IdentifierNode origin; // Dummy origin.
358 a.data_deps()[0].origin = &origin;
359 a.SetToolchain(setup.toolchain());
360 ASSERT_TRUE(a.OnResolved(&err)) << err.help_text();
363 // Tests that A -> Group -> B where the group is visible from A but B isn't,
364 // passes visibility even though the group's deps get expanded into A.
365 TEST(Target, VisibilityGroup) {
366 TestWithScope setup;
367 Err err;
369 IdentifierNode origin; // Dummy origin.
371 // B has private visibility. This lets the group see it since the group is in
372 // the same directory.
373 Target b(setup.settings(), Label(SourceDir("//private/"), "b"));
374 b.set_output_type(Target::STATIC_LIBRARY);
375 b.SetToolchain(setup.toolchain());
376 b.visibility().SetPrivate(b.label().dir());
377 ASSERT_TRUE(b.OnResolved(&err));
379 // The group has public visibility and depends on b.
380 Target g(setup.settings(), Label(SourceDir("//private/"), "g"));
381 g.set_output_type(Target::GROUP);
382 g.SetToolchain(setup.toolchain());
383 g.private_deps().push_back(LabelTargetPair(&b));
384 g.private_deps()[0].origin = &origin;
385 g.visibility().SetPublic();
386 ASSERT_TRUE(b.OnResolved(&err));
388 // Make a target depending on "g". This should succeed.
389 Target a(setup.settings(), Label(SourceDir("//app/"), "a"));
390 a.set_output_type(Target::EXECUTABLE);
391 a.private_deps().push_back(LabelTargetPair(&g));
392 a.private_deps()[0].origin = &origin;
393 a.SetToolchain(setup.toolchain());
394 ASSERT_TRUE(a.OnResolved(&err));
397 // Verifies that only testonly targets can depend on other testonly targets.
398 // Many of the above dependency checking cases covered the non-testonly
399 // case.
400 TEST(Target, Testonly) {
401 TestWithScope setup;
402 Err err;
404 // "testlib" is a test-only library.
405 Target testlib(setup.settings(), Label(SourceDir("//test/"), "testlib"));
406 testlib.set_testonly(true);
407 testlib.set_output_type(Target::STATIC_LIBRARY);
408 testlib.visibility().SetPublic();
409 testlib.SetToolchain(setup.toolchain());
410 ASSERT_TRUE(testlib.OnResolved(&err));
412 // "test" is a test-only executable depending on testlib, this is OK.
413 Target test(setup.settings(), Label(SourceDir("//test/"), "test"));
414 test.set_testonly(true);
415 test.set_output_type(Target::EXECUTABLE);
416 test.private_deps().push_back(LabelTargetPair(&testlib));
417 test.SetToolchain(setup.toolchain());
418 ASSERT_TRUE(test.OnResolved(&err));
420 // "product" is a non-test depending on testlib. This should fail.
421 Target product(setup.settings(), Label(SourceDir("//app/"), "product"));
422 product.set_testonly(false);
423 product.set_output_type(Target::EXECUTABLE);
424 product.private_deps().push_back(LabelTargetPair(&testlib));
425 product.SetToolchain(setup.toolchain());
426 ASSERT_FALSE(product.OnResolved(&err));
429 TEST(Target, PublicConfigs) {
430 TestWithScope setup;
431 Err err;
433 Label pub_config_label(SourceDir("//a/"), "pubconfig");
434 Config pub_config(setup.settings(), pub_config_label);
436 // This is the destination target that has a public config.
437 Target dest(setup.settings(), Label(SourceDir("//a/"), "a"));
438 dest.set_output_type(Target::SOURCE_SET);
439 dest.visibility().SetPublic();
440 dest.SetToolchain(setup.toolchain());
441 dest.public_configs().push_back(LabelConfigPair(&pub_config));
442 ASSERT_TRUE(dest.OnResolved(&err));
444 // This target has a public dependency on dest.
445 Target pub(setup.settings(), Label(SourceDir("//a/"), "pub"));
446 pub.set_output_type(Target::SOURCE_SET);
447 pub.visibility().SetPublic();
448 pub.SetToolchain(setup.toolchain());
449 pub.public_deps().push_back(LabelTargetPair(&dest));
450 ASSERT_TRUE(pub.OnResolved(&err));
452 // Depending on the target with the public dependency should forward dest's
453 // to the current target.
454 Target dep_on_pub(setup.settings(), Label(SourceDir("//a/"), "dop"));
455 dep_on_pub.set_output_type(Target::SOURCE_SET);
456 dep_on_pub.visibility().SetPublic();
457 dep_on_pub.SetToolchain(setup.toolchain());
458 dep_on_pub.private_deps().push_back(LabelTargetPair(&pub));
459 ASSERT_TRUE(dep_on_pub.OnResolved(&err));
460 ASSERT_EQ(1u, dep_on_pub.configs().size());
461 EXPECT_EQ(&pub_config, dep_on_pub.configs()[0].ptr);
463 // This target has a private dependency on dest for forwards configs.
464 Target forward(setup.settings(), Label(SourceDir("//a/"), "f"));
465 forward.set_output_type(Target::SOURCE_SET);
466 forward.visibility().SetPublic();
467 forward.SetToolchain(setup.toolchain());
468 forward.private_deps().push_back(LabelTargetPair(&dest));
469 forward.forward_dependent_configs().push_back(LabelTargetPair(&dest));
470 ASSERT_TRUE(forward.OnResolved(&err));
472 // Depending on the forward target should apply the config.
473 Target dep_on_forward(setup.settings(), Label(SourceDir("//a/"), "dof"));
474 dep_on_forward.set_output_type(Target::SOURCE_SET);
475 dep_on_forward.visibility().SetPublic();
476 dep_on_forward.SetToolchain(setup.toolchain());
477 dep_on_forward.private_deps().push_back(LabelTargetPair(&forward));
478 ASSERT_TRUE(dep_on_forward.OnResolved(&err));
479 ASSERT_EQ(1u, dep_on_forward.configs().size());
480 EXPECT_EQ(&pub_config, dep_on_forward.configs()[0].ptr);
483 // Tests that different link/depend outputs work for solink tools.
484 TEST(Target, LinkAndDepOutputs) {
485 TestWithScope setup;
486 Err err;
488 Toolchain toolchain(setup.settings(), Label(SourceDir("//tc/"), "tc"));
490 scoped_ptr<Tool> solink_tool(new Tool());
491 solink_tool->set_output_prefix("lib");
492 solink_tool->set_default_output_extension(".so");
494 const char kLinkPattern[] =
495 "{{root_out_dir}}/{{target_output_name}}{{output_extension}}";
496 SubstitutionPattern link_output = SubstitutionPattern::MakeForTest(
497 kLinkPattern);
498 solink_tool->set_link_output(link_output);
500 const char kDependPattern[] =
501 "{{root_out_dir}}/{{target_output_name}}{{output_extension}}.TOC";
502 SubstitutionPattern depend_output = SubstitutionPattern::MakeForTest(
503 kDependPattern);
504 solink_tool->set_depend_output(depend_output);
506 solink_tool->set_outputs(SubstitutionList::MakeForTest(
507 kLinkPattern, kDependPattern));
509 toolchain.SetTool(Toolchain::TYPE_SOLINK, solink_tool.Pass());
511 Target target(setup.settings(), Label(SourceDir("//a/"), "a"));
512 target.set_output_type(Target::SHARED_LIBRARY);
513 target.SetToolchain(&toolchain);
514 ASSERT_TRUE(target.OnResolved(&err));
516 EXPECT_EQ("./liba.so", target.link_output_file().value());
517 EXPECT_EQ("./liba.so.TOC", target.dependency_output_file().value());
520 // Shared libraries should be inherited across public shared liobrary
521 // boundaries.
522 TEST(Target, SharedInheritance) {
523 TestWithScope setup;
524 Err err;
526 // Create two leaf shared libraries.
527 Target pub(setup.settings(), Label(SourceDir("//foo/"), "pub"));
528 pub.set_output_type(Target::SHARED_LIBRARY);
529 pub.visibility().SetPublic();
530 pub.SetToolchain(setup.toolchain());
531 ASSERT_TRUE(pub.OnResolved(&err));
533 Target priv(setup.settings(), Label(SourceDir("//foo/"), "priv"));
534 priv.set_output_type(Target::SHARED_LIBRARY);
535 priv.visibility().SetPublic();
536 priv.SetToolchain(setup.toolchain());
537 ASSERT_TRUE(priv.OnResolved(&err));
539 // Intermediate shared library with the leaf shared libraries as
540 // dependencies, one public, one private.
541 Target inter(setup.settings(), Label(SourceDir("//foo/"), "inter"));
542 inter.set_output_type(Target::SHARED_LIBRARY);
543 inter.visibility().SetPublic();
544 inter.public_deps().push_back(LabelTargetPair(&pub));
545 inter.private_deps().push_back(LabelTargetPair(&priv));
546 inter.SetToolchain(setup.toolchain());
547 ASSERT_TRUE(inter.OnResolved(&err));
549 // The intermediate shared library should have both "pub" and "priv" in its
550 // inherited libraries.
551 std::vector<const Target*> inter_inherited =
552 inter.inherited_libraries().GetOrdered();
553 ASSERT_EQ(2u, inter_inherited.size());
554 EXPECT_EQ(&pub, inter_inherited[0]);
555 EXPECT_EQ(&priv, inter_inherited[1]);
557 // Make a toplevel executable target depending on the intermediate one.
558 Target exe(setup.settings(), Label(SourceDir("//foo/"), "exe"));
559 exe.set_output_type(Target::SHARED_LIBRARY);
560 exe.visibility().SetPublic();
561 exe.private_deps().push_back(LabelTargetPair(&inter));
562 exe.SetToolchain(setup.toolchain());
563 ASSERT_TRUE(exe.OnResolved(&err));
565 // The exe's inherited libraries should be "inter" (because it depended
566 // directly on it) and "pub" (because inter depended publicly on it).
567 std::vector<const Target*> exe_inherited =
568 exe.inherited_libraries().GetOrdered();
569 ASSERT_EQ(2u, exe_inherited.size());
570 EXPECT_EQ(&inter, exe_inherited[0]);
571 EXPECT_EQ(&pub, exe_inherited[1]);