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
) {
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
) {
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
) {
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
) {
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
) {
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
) {
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
) {
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
) {
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
) {
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
) {
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
400 TEST(Target
, Testonly
) {
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
) {
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
) {
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(
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(
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
522 TEST(Target
, SharedInheritance
) {
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]);