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/scheduler.h"
9 #include "tools/gn/settings.h"
10 #include "tools/gn/target.h"
11 #include "tools/gn/test_with_scope.h"
12 #include "tools/gn/toolchain.h"
16 // Asserts that the current global scheduler has a single unknown generated
17 // file with the given name from the given target.
18 void AssertSchedulerHasOneUnknownFileMatching(const Target
* target
,
19 const SourceFile
& file
) {
20 auto unknown
= g_scheduler
->GetUnknownGeneratedInputs();
21 ASSERT_EQ(1u, unknown
.size()); // Should be one unknown file.
22 auto found
= unknown
.find(file
);
23 ASSERT_TRUE(found
!= unknown
.end()) << file
.value();
24 EXPECT_TRUE(target
== found
->second
)
25 << "Target doesn't match. Expected\n "
26 << target
->label().GetUserVisibleName(false)
27 << "\nBut got\n " << found
->second
->label().GetUserVisibleName(false);
32 // Tests that lib[_dir]s are inherited across deps boundaries for static
33 // libraries but not executables.
34 TEST(Target
, LibInheritance
) {
38 const std::string
lib("foo");
39 const SourceDir
libdir("/foo_dir/");
41 // Leaf target with ldflags set.
42 TestTarget
z(setup
, "//foo:z", Target::STATIC_LIBRARY
);
43 z
.config_values().libs().push_back(lib
);
44 z
.config_values().lib_dirs().push_back(libdir
);
45 ASSERT_TRUE(z
.OnResolved(&err
));
47 // All lib[_dir]s should be set when target is resolved.
48 ASSERT_EQ(1u, z
.all_libs().size());
49 EXPECT_EQ(lib
, z
.all_libs()[0]);
50 ASSERT_EQ(1u, z
.all_lib_dirs().size());
51 EXPECT_EQ(libdir
, z
.all_lib_dirs()[0]);
53 // Shared library target should inherit the libs from the static library
54 // and its own. Its own flag should be before the inherited one.
55 const std::string
second_lib("bar");
56 const SourceDir
second_libdir("/bar_dir/");
57 TestTarget
shared(setup
, "//foo:shared", Target::SHARED_LIBRARY
);
58 shared
.config_values().libs().push_back(second_lib
);
59 shared
.config_values().lib_dirs().push_back(second_libdir
);
60 shared
.private_deps().push_back(LabelTargetPair(&z
));
61 ASSERT_TRUE(shared
.OnResolved(&err
));
63 ASSERT_EQ(2u, shared
.all_libs().size());
64 EXPECT_EQ(second_lib
, shared
.all_libs()[0]);
65 EXPECT_EQ(lib
, shared
.all_libs()[1]);
66 ASSERT_EQ(2u, shared
.all_lib_dirs().size());
67 EXPECT_EQ(second_libdir
, shared
.all_lib_dirs()[0]);
68 EXPECT_EQ(libdir
, shared
.all_lib_dirs()[1]);
70 // Executable target shouldn't get either by depending on shared.
71 TestTarget
exec(setup
, "//foo:exec", Target::EXECUTABLE
);
72 exec
.private_deps().push_back(LabelTargetPair(&shared
));
73 ASSERT_TRUE(exec
.OnResolved(&err
));
74 EXPECT_EQ(0u, exec
.all_libs().size());
75 EXPECT_EQ(0u, exec
.all_lib_dirs().size());
78 // Test all_dependent_configs, public_config inheritance, and
79 // forward_dependent_configs_from
80 TEST(Target
, DependentConfigs
) {
84 // Set up a dependency chain of a -> b -> c
85 TestTarget
a(setup
, "//foo:a", Target::EXECUTABLE
);
86 TestTarget
b(setup
, "//foo:b", Target::STATIC_LIBRARY
);
87 TestTarget
c(setup
, "//foo:c", Target::STATIC_LIBRARY
);
88 a
.private_deps().push_back(LabelTargetPair(&b
));
89 b
.private_deps().push_back(LabelTargetPair(&c
));
91 // Normal non-inherited config.
92 Config
config(setup
.settings(), Label(SourceDir("//foo/"), "config"));
93 ASSERT_TRUE(config
.OnResolved(&err
));
94 c
.configs().push_back(LabelConfigPair(&config
));
96 // All dependent config.
97 Config
all(setup
.settings(), Label(SourceDir("//foo/"), "all"));
98 ASSERT_TRUE(all
.OnResolved(&err
));
99 c
.all_dependent_configs().push_back(LabelConfigPair(&all
));
101 // Direct dependent config.
102 Config
direct(setup
.settings(), Label(SourceDir("//foo/"), "direct"));
103 ASSERT_TRUE(direct
.OnResolved(&err
));
104 c
.public_configs().push_back(LabelConfigPair(&direct
));
106 ASSERT_TRUE(c
.OnResolved(&err
));
107 ASSERT_TRUE(b
.OnResolved(&err
));
108 ASSERT_TRUE(a
.OnResolved(&err
));
110 // B should have gotten both dependent configs from C.
111 ASSERT_EQ(2u, b
.configs().size());
112 EXPECT_EQ(&all
, b
.configs()[0].ptr
);
113 EXPECT_EQ(&direct
, b
.configs()[1].ptr
);
114 ASSERT_EQ(1u, b
.all_dependent_configs().size());
115 EXPECT_EQ(&all
, b
.all_dependent_configs()[0].ptr
);
117 // A should have just gotten the "all" dependent config from C.
118 ASSERT_EQ(1u, a
.configs().size());
119 EXPECT_EQ(&all
, a
.configs()[0].ptr
);
120 EXPECT_EQ(&all
, a
.all_dependent_configs()[0].ptr
);
122 // Making an an alternate A and B with B forwarding the direct dependents.
123 TestTarget
a_fwd(setup
, "//foo:a_fwd", Target::EXECUTABLE
);
124 TestTarget
b_fwd(setup
, "//foo:b_fwd", Target::STATIC_LIBRARY
);
125 a_fwd
.private_deps().push_back(LabelTargetPair(&b_fwd
));
126 b_fwd
.private_deps().push_back(LabelTargetPair(&c
));
127 b_fwd
.forward_dependent_configs().push_back(LabelTargetPair(&c
));
129 ASSERT_TRUE(b_fwd
.OnResolved(&err
));
130 ASSERT_TRUE(a_fwd
.OnResolved(&err
));
132 // A_fwd should now have both configs.
133 ASSERT_EQ(2u, a_fwd
.configs().size());
134 EXPECT_EQ(&all
, a_fwd
.configs()[0].ptr
);
135 EXPECT_EQ(&direct
, a_fwd
.configs()[1].ptr
);
136 ASSERT_EQ(1u, a_fwd
.all_dependent_configs().size());
137 EXPECT_EQ(&all
, a_fwd
.all_dependent_configs()[0].ptr
);
140 TEST(Target
, InheritLibs
) {
144 // Create a dependency chain:
145 // A (executable) -> B (shared lib) -> C (static lib) -> D (source set)
146 TestTarget
a(setup
, "//foo:a", Target::EXECUTABLE
);
147 TestTarget
b(setup
, "//foo:b", Target::SHARED_LIBRARY
);
148 TestTarget
c(setup
, "//foo:c", Target::STATIC_LIBRARY
);
149 TestTarget
d(setup
, "//foo:d", Target::SOURCE_SET
);
150 a
.private_deps().push_back(LabelTargetPair(&b
));
151 b
.private_deps().push_back(LabelTargetPair(&c
));
152 c
.private_deps().push_back(LabelTargetPair(&d
));
154 ASSERT_TRUE(d
.OnResolved(&err
));
155 ASSERT_TRUE(c
.OnResolved(&err
));
156 ASSERT_TRUE(b
.OnResolved(&err
));
157 ASSERT_TRUE(a
.OnResolved(&err
));
159 // C should have D in its inherited libs.
160 std::vector
<const Target
*> c_inherited
= c
.inherited_libraries().GetOrdered();
161 ASSERT_EQ(1u, c_inherited
.size());
162 EXPECT_EQ(&d
, c_inherited
[0]);
164 // B should have C and D in its inherited libs.
165 std::vector
<const Target
*> b_inherited
= b
.inherited_libraries().GetOrdered();
166 ASSERT_EQ(2u, b_inherited
.size());
167 EXPECT_EQ(&c
, b_inherited
[0]);
168 EXPECT_EQ(&d
, b_inherited
[1]);
170 // A should have B in its inherited libs, but not any others (the shared
171 // library will include the static library and source set).
172 std::vector
<const Target
*> a_inherited
= a
.inherited_libraries().GetOrdered();
173 ASSERT_EQ(1u, a_inherited
.size());
174 EXPECT_EQ(&b
, a_inherited
[0]);
177 TEST(Target
, InheritCompleteStaticLib
) {
181 // Create a dependency chain:
182 // A (executable) -> B (complete static lib) -> C (source set)
183 TestTarget
a(setup
, "//foo:a", Target::EXECUTABLE
);
184 TestTarget
b(setup
, "//foo:b", Target::STATIC_LIBRARY
);
185 b
.set_complete_static_lib(true);
186 TestTarget
c(setup
, "//foo:c", Target::SOURCE_SET
);
187 a
.public_deps().push_back(LabelTargetPair(&b
));
188 b
.public_deps().push_back(LabelTargetPair(&c
));
190 ASSERT_TRUE(c
.OnResolved(&err
));
191 ASSERT_TRUE(b
.OnResolved(&err
));
192 ASSERT_TRUE(a
.OnResolved(&err
));
194 // B should have C in its inherited libs.
195 std::vector
<const Target
*> b_inherited
= b
.inherited_libraries().GetOrdered();
196 ASSERT_EQ(1u, b_inherited
.size());
197 EXPECT_EQ(&c
, b_inherited
[0]);
199 // A should have B in its inherited libs, but not any others (the complete
200 // static library will include the source set).
201 std::vector
<const Target
*> a_inherited
= a
.inherited_libraries().GetOrdered();
202 EXPECT_EQ(1u, a_inherited
.size());
203 EXPECT_EQ(&b
, a_inherited
[0]);
206 TEST(Target
, InheritCompleteStaticLibNoDirectStaticLibDeps
) {
210 // Create a dependency chain:
211 // A (complete static lib) -> B (static lib)
212 TestTarget
a(setup
, "//foo:a", Target::STATIC_LIBRARY
);
213 a
.set_complete_static_lib(true);
214 TestTarget
b(setup
, "//foo:b", Target::STATIC_LIBRARY
);
216 a
.public_deps().push_back(LabelTargetPair(&b
));
217 ASSERT_TRUE(b
.OnResolved(&err
));
218 ASSERT_FALSE(a
.OnResolved(&err
));
221 TEST(Target
, InheritCompleteStaticLibNoIheritedStaticLibDeps
) {
225 // Create a dependency chain:
226 // A (complete static lib) -> B (source set) -> C (static lib)
227 TestTarget
a(setup
, "//foo:a", Target::STATIC_LIBRARY
);
228 a
.set_complete_static_lib(true);
229 TestTarget
b(setup
, "//foo:b", Target::SOURCE_SET
);
230 TestTarget
c(setup
, "//foo:c", Target::STATIC_LIBRARY
);
232 a
.public_deps().push_back(LabelTargetPair(&b
));
233 b
.public_deps().push_back(LabelTargetPair(&c
));
235 ASSERT_TRUE(c
.OnResolved(&err
));
236 ASSERT_TRUE(b
.OnResolved(&err
));
237 ASSERT_FALSE(a
.OnResolved(&err
));
240 TEST(Target
, GetComputedOutputName
) {
244 // Basic target with no prefix (executable type tool in the TestWithScope has
245 // no prefix) or output name.
246 TestTarget
basic(setup
, "//foo:bar", Target::EXECUTABLE
);
247 ASSERT_TRUE(basic
.OnResolved(&err
));
248 EXPECT_EQ("bar", basic
.GetComputedOutputName(false));
249 EXPECT_EQ("bar", basic
.GetComputedOutputName(true));
251 // Target with no prefix but an output name.
252 TestTarget
with_name(setup
, "//foo:bar", Target::EXECUTABLE
);
253 with_name
.set_output_name("myoutput");
254 ASSERT_TRUE(with_name
.OnResolved(&err
));
255 EXPECT_EQ("myoutput", with_name
.GetComputedOutputName(false));
256 EXPECT_EQ("myoutput", with_name
.GetComputedOutputName(true));
258 // Target with a "lib" prefix (the static library tool in the TestWithScope
259 // should specify a "lib" output prefix).
260 TestTarget
with_prefix(setup
, "//foo:bar", Target::STATIC_LIBRARY
);
261 ASSERT_TRUE(with_prefix
.OnResolved(&err
));
262 EXPECT_EQ("bar", with_prefix
.GetComputedOutputName(false));
263 EXPECT_EQ("libbar", with_prefix
.GetComputedOutputName(true));
265 // Target with a "lib" prefix that already has it applied. The prefix should
266 // not duplicate something already in the target name.
267 TestTarget
dup_prefix(setup
, "//foo:bar", Target::STATIC_LIBRARY
);
268 dup_prefix
.set_output_name("libbar");
269 ASSERT_TRUE(dup_prefix
.OnResolved(&err
));
270 EXPECT_EQ("libbar", dup_prefix
.GetComputedOutputName(false));
271 EXPECT_EQ("libbar", dup_prefix
.GetComputedOutputName(true));
274 // Test visibility failure case.
275 TEST(Target
, VisibilityFails
) {
279 TestTarget
b(setup
, "//private:b", Target::STATIC_LIBRARY
);
280 b
.visibility().SetPrivate(b
.label().dir());
281 ASSERT_TRUE(b
.OnResolved(&err
));
283 // Make a target depending on "b". The dependency must have an origin to mark
284 // it as user-set so we check visibility. This check should fail.
285 TestTarget
a(setup
, "//app:a", Target::EXECUTABLE
);
286 a
.private_deps().push_back(LabelTargetPair(&b
));
287 IdentifierNode origin
; // Dummy origin.
288 a
.private_deps()[0].origin
= &origin
;
289 ASSERT_FALSE(a
.OnResolved(&err
));
292 // Test visibility with a single data_dep.
293 TEST(Target
, VisibilityDatadeps
) {
297 TestTarget
b(setup
, "//public:b", Target::STATIC_LIBRARY
);
298 ASSERT_TRUE(b
.OnResolved(&err
));
300 // Make a target depending on "b". The dependency must have an origin to mark
301 // it as user-set so we check visibility. This check should fail.
302 TestTarget
a(setup
, "//app:a", Target::EXECUTABLE
);
303 a
.data_deps().push_back(LabelTargetPair(&b
));
304 IdentifierNode origin
; // Dummy origin.
305 a
.data_deps()[0].origin
= &origin
;
306 ASSERT_TRUE(a
.OnResolved(&err
)) << err
.help_text();
309 // Tests that A -> Group -> B where the group is visible from A but B isn't,
310 // passes visibility even though the group's deps get expanded into A.
311 TEST(Target
, VisibilityGroup
) {
315 IdentifierNode origin
; // Dummy origin.
317 // B has private visibility. This lets the group see it since the group is in
318 // the same directory.
319 TestTarget
b(setup
, "//private:b", Target::STATIC_LIBRARY
);
320 b
.visibility().SetPrivate(b
.label().dir());
321 ASSERT_TRUE(b
.OnResolved(&err
));
323 // The group has public visibility and depends on b.
324 TestTarget
g(setup
, "//public:g", Target::GROUP
);
325 g
.private_deps().push_back(LabelTargetPair(&b
));
326 g
.private_deps()[0].origin
= &origin
;
327 ASSERT_TRUE(b
.OnResolved(&err
));
329 // Make a target depending on "g". This should succeed.
330 TestTarget
a(setup
, "//app:a", Target::EXECUTABLE
);
331 a
.private_deps().push_back(LabelTargetPair(&g
));
332 a
.private_deps()[0].origin
= &origin
;
333 ASSERT_TRUE(a
.OnResolved(&err
));
336 // Verifies that only testonly targets can depend on other testonly targets.
337 // Many of the above dependency checking cases covered the non-testonly
339 TEST(Target
, Testonly
) {
343 // "testlib" is a test-only library.
344 TestTarget
testlib(setup
, "//test:testlib", Target::STATIC_LIBRARY
);
345 testlib
.set_testonly(true);
346 ASSERT_TRUE(testlib
.OnResolved(&err
));
348 // "test" is a test-only executable depending on testlib, this is OK.
349 TestTarget
test(setup
, "//test:test", Target::EXECUTABLE
);
350 test
.set_testonly(true);
351 test
.private_deps().push_back(LabelTargetPair(&testlib
));
352 ASSERT_TRUE(test
.OnResolved(&err
));
354 // "product" is a non-test depending on testlib. This should fail.
355 TestTarget
product(setup
, "//app:product", Target::EXECUTABLE
);
356 product
.set_testonly(false);
357 product
.private_deps().push_back(LabelTargetPair(&testlib
));
358 ASSERT_FALSE(product
.OnResolved(&err
));
361 TEST(Target
, PublicConfigs
) {
365 Label
pub_config_label(SourceDir("//a/"), "pubconfig");
366 Config
pub_config(setup
.settings(), pub_config_label
);
367 ASSERT_TRUE(pub_config
.OnResolved(&err
));
369 // This is the destination target that has a public config.
370 TestTarget
dest(setup
, "//a:a", Target::SOURCE_SET
);
371 dest
.public_configs().push_back(LabelConfigPair(&pub_config
));
372 ASSERT_TRUE(dest
.OnResolved(&err
));
374 // This target has a public dependency on dest.
375 TestTarget
pub(setup
, "//a:pub", Target::SOURCE_SET
);
376 pub
.public_deps().push_back(LabelTargetPair(&dest
));
377 ASSERT_TRUE(pub
.OnResolved(&err
));
379 // Depending on the target with the public dependency should forward dest's
380 // to the current target.
381 TestTarget
dep_on_pub(setup
, "//a:dop", Target::SOURCE_SET
);
382 dep_on_pub
.private_deps().push_back(LabelTargetPair(&pub
));
383 ASSERT_TRUE(dep_on_pub
.OnResolved(&err
));
384 ASSERT_EQ(1u, dep_on_pub
.configs().size());
385 EXPECT_EQ(&pub_config
, dep_on_pub
.configs()[0].ptr
);
387 // This target has a private dependency on dest for forwards configs.
388 TestTarget
forward(setup
, "//a:f", Target::SOURCE_SET
);
389 forward
.private_deps().push_back(LabelTargetPair(&dest
));
390 forward
.forward_dependent_configs().push_back(LabelTargetPair(&dest
));
391 ASSERT_TRUE(forward
.OnResolved(&err
));
393 // Depending on the forward target should apply the config.
394 TestTarget
dep_on_forward(setup
, "//a:dof", Target::SOURCE_SET
);
395 dep_on_forward
.private_deps().push_back(LabelTargetPair(&forward
));
396 ASSERT_TRUE(dep_on_forward
.OnResolved(&err
));
397 ASSERT_EQ(1u, dep_on_forward
.configs().size());
398 EXPECT_EQ(&pub_config
, dep_on_forward
.configs()[0].ptr
);
401 // Tests that different link/depend outputs work for solink tools.
402 TEST(Target
, LinkAndDepOutputs
) {
406 Toolchain
toolchain(setup
.settings(), Label(SourceDir("//tc/"), "tc"));
408 scoped_ptr
<Tool
> solink_tool(new Tool());
409 solink_tool
->set_output_prefix("lib");
410 solink_tool
->set_default_output_extension(".so");
412 const char kLinkPattern
[] =
413 "{{root_out_dir}}/{{target_output_name}}{{output_extension}}";
414 SubstitutionPattern link_output
= SubstitutionPattern::MakeForTest(
416 solink_tool
->set_link_output(link_output
);
418 const char kDependPattern
[] =
419 "{{root_out_dir}}/{{target_output_name}}{{output_extension}}.TOC";
420 SubstitutionPattern depend_output
= SubstitutionPattern::MakeForTest(
422 solink_tool
->set_depend_output(depend_output
);
424 solink_tool
->set_outputs(SubstitutionList::MakeForTest(
425 kLinkPattern
, kDependPattern
));
427 toolchain
.SetTool(Toolchain::TYPE_SOLINK
, solink_tool
.Pass());
429 Target
target(setup
.settings(), Label(SourceDir("//a/"), "a"));
430 target
.set_output_type(Target::SHARED_LIBRARY
);
431 target
.SetToolchain(&toolchain
);
432 ASSERT_TRUE(target
.OnResolved(&err
));
434 EXPECT_EQ("./liba.so", target
.link_output_file().value());
435 EXPECT_EQ("./liba.so.TOC", target
.dependency_output_file().value());
438 // Shared libraries should be inherited across public shared liobrary
440 TEST(Target
, SharedInheritance
) {
444 // Create two leaf shared libraries.
445 TestTarget
pub(setup
, "//foo:pub", Target::SHARED_LIBRARY
);
446 ASSERT_TRUE(pub
.OnResolved(&err
));
448 TestTarget
priv(setup
, "//foo:priv", Target::SHARED_LIBRARY
);
449 ASSERT_TRUE(priv
.OnResolved(&err
));
451 // Intermediate shared library with the leaf shared libraries as
452 // dependencies, one public, one private.
453 TestTarget
inter(setup
, "//foo:inter", Target::SHARED_LIBRARY
);
454 inter
.public_deps().push_back(LabelTargetPair(&pub
));
455 inter
.private_deps().push_back(LabelTargetPair(&priv
));
456 ASSERT_TRUE(inter
.OnResolved(&err
));
458 // The intermediate shared library should have both "pub" and "priv" in its
459 // inherited libraries.
460 std::vector
<const Target
*> inter_inherited
=
461 inter
.inherited_libraries().GetOrdered();
462 ASSERT_EQ(2u, inter_inherited
.size());
463 EXPECT_EQ(&pub
, inter_inherited
[0]);
464 EXPECT_EQ(&priv
, inter_inherited
[1]);
466 // Make a toplevel executable target depending on the intermediate one.
467 TestTarget
exe(setup
, "//foo:exe", Target::SHARED_LIBRARY
);
468 exe
.private_deps().push_back(LabelTargetPair(&inter
));
469 ASSERT_TRUE(exe
.OnResolved(&err
));
471 // The exe's inherited libraries should be "inter" (because it depended
472 // directly on it) and "pub" (because inter depended publicly on it).
473 std::vector
<const Target
*> exe_inherited
=
474 exe
.inherited_libraries().GetOrdered();
475 ASSERT_EQ(2u, exe_inherited
.size());
476 EXPECT_EQ(&inter
, exe_inherited
[0]);
477 EXPECT_EQ(&pub
, exe_inherited
[1]);
480 TEST(Target
, GeneratedInputs
) {
485 SourceFile
generated_file("//out/Debug/generated.cc");
487 // This target has a generated input and no dependency makes it.
488 TestTarget
non_existent_generator(setup
, "//foo:non_existent_generator",
490 non_existent_generator
.sources().push_back(generated_file
);
491 EXPECT_TRUE(non_existent_generator
.OnResolved(&err
)) << err
.message();
492 AssertSchedulerHasOneUnknownFileMatching(&non_existent_generator
,
494 scheduler
.ClearUnknownGeneratedInputsAndWrittenFiles();
496 // Make a target that generates the file.
497 TestTarget
generator(setup
, "//foo:generator", Target::ACTION
);
498 generator
.action_values().outputs() =
499 SubstitutionList::MakeForTest(generated_file
.value().c_str());
501 EXPECT_TRUE(generator
.OnResolved(&err
)) << err
.message();
503 // A target that depends on the generator that uses the file as a source
504 // should be OK. This uses a private dep (will be used later).
505 TestTarget
existent_generator(setup
, "//foo:existent_generator",
506 Target::SHARED_LIBRARY
);
507 existent_generator
.sources().push_back(generated_file
);
508 existent_generator
.private_deps().push_back(LabelTargetPair(&generator
));
509 EXPECT_TRUE(existent_generator
.OnResolved(&err
)) << err
.message();
510 EXPECT_TRUE(scheduler
.GetUnknownGeneratedInputs().empty());
512 // A target that depends on the previous one should *not* be allowed to
513 // use the generated file, because existent_generator used private deps.
515 // indirect_private --> existent_generator --[private]--> generator
516 TestTarget
indirect_private(setup
, "//foo:indirect_private",
518 indirect_private
.sources().push_back(generated_file
);
519 indirect_private
.public_deps().push_back(
520 LabelTargetPair(&existent_generator
));
521 EXPECT_TRUE(indirect_private
.OnResolved(&err
));
522 AssertSchedulerHasOneUnknownFileMatching(&indirect_private
, generated_file
);
523 scheduler
.ClearUnknownGeneratedInputsAndWrittenFiles();
525 // Now make a chain like the above but with all public deps, it should be OK.
526 TestTarget
existent_public(setup
, "//foo:existent_public",
527 Target::SHARED_LIBRARY
);
528 existent_public
.public_deps().push_back(LabelTargetPair(&generator
));
529 EXPECT_TRUE(existent_public
.OnResolved(&err
)) << err
.message();
530 TestTarget
indirect_public(setup
, "//foo:indirect_public",
532 indirect_public
.sources().push_back(generated_file
);
533 indirect_public
.public_deps().push_back(LabelTargetPair(&existent_public
));
534 EXPECT_TRUE(indirect_public
.OnResolved(&err
)) << err
.message();
535 EXPECT_TRUE(scheduler
.GetUnknownGeneratedInputs().empty());
538 // This is sort of a Scheduler test, but is related to the above test more.
539 TEST(Target
, WriteFileGeneratedInputs
) {
544 SourceFile
generated_file("//out/Debug/generated.data");
546 // This target has a generated input and no dependency makes it.
547 TestTarget
non_existent_generator(setup
, "//foo:non_existent_generator",
549 non_existent_generator
.sources().push_back(generated_file
);
550 EXPECT_TRUE(non_existent_generator
.OnResolved(&err
));
551 AssertSchedulerHasOneUnknownFileMatching(&non_existent_generator
,
553 scheduler
.ClearUnknownGeneratedInputsAndWrittenFiles();
555 // This target has a generated file and we've decared we write it.
556 TestTarget
existent_generator(setup
, "//foo:existent_generator",
558 existent_generator
.sources().push_back(generated_file
);
559 EXPECT_TRUE(existent_generator
.OnResolved(&err
));
560 scheduler
.AddWrittenFile(generated_file
);
563 EXPECT_TRUE(scheduler
.GetUnknownGeneratedInputs().empty());
566 TEST(Target
, ResolvePrecompiledHeaders
) {
570 Target
target(setup
.settings(), Label(SourceDir("//foo/"), "bar"));
572 // Target with no settings, no configs, should be a no-op.
573 EXPECT_TRUE(target
.ResolvePrecompiledHeaders(&err
));
575 // Config with PCH values.
576 Config
config_1(setup
.settings(), Label(SourceDir("//foo/"), "c1"));
577 std::string
pch_1("pch.h");
578 SourceFile
pcs_1("//pcs.cc");
579 config_1
.own_values().set_precompiled_header(pch_1
);
580 config_1
.own_values().set_precompiled_source(pcs_1
);
581 ASSERT_TRUE(config_1
.OnResolved(&err
));
582 target
.configs().push_back(LabelConfigPair(&config_1
));
584 // No PCH info specified on target, but the config specifies one, the
585 // values should get copied to the target.
586 EXPECT_TRUE(target
.ResolvePrecompiledHeaders(&err
));
587 EXPECT_EQ(pch_1
, target
.config_values().precompiled_header());
588 EXPECT_TRUE(target
.config_values().precompiled_source() == pcs_1
);
590 // Now both target and config have matching PCH values. Resolving again
591 // should be a no-op since they all match.
592 EXPECT_TRUE(target
.ResolvePrecompiledHeaders(&err
));
593 EXPECT_TRUE(target
.config_values().precompiled_header() == pch_1
);
594 EXPECT_TRUE(target
.config_values().precompiled_source() == pcs_1
);
596 // Second config with different PCH values.
597 Config
config_2(setup
.settings(), Label(SourceDir("//foo/"), "c2"));
598 std::string
pch_2("pch2.h");
599 SourceFile
pcs_2("//pcs2.cc");
600 config_2
.own_values().set_precompiled_header(pch_2
);
601 config_2
.own_values().set_precompiled_source(pcs_2
);
602 ASSERT_TRUE(config_2
.OnResolved(&err
));
603 target
.configs().push_back(LabelConfigPair(&config_2
));
605 // This should be an error since they don't match.
606 EXPECT_FALSE(target
.ResolvePrecompiledHeaders(&err
));
608 // Make sure the proper labels are blamed.
610 "The target //foo:bar\n"
611 "has conflicting precompiled header settings.\n"
615 " source: //pcs.cc\n"
619 " source: //pcs2.cc",