Add the ability to code generated prepopulated static nested structs
[chromium-blink-merge.git] / tools / gn / target_unittest.cc
blobc9e0b1e607d69da76a52d1dee3c6861c12692c29
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"
14 namespace {
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);
30 } // namespace
32 // Tests that lib[_dir]s are inherited across deps boundaries for static
33 // libraries but not executables.
34 TEST(Target, LibInheritance) {
35 TestWithScope setup;
36 Err err;
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) {
81 TestWithScope setup;
82 Err err;
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 c.configs().push_back(LabelConfigPair(&config));
95 // All dependent config.
96 Config all(setup.settings(), Label(SourceDir("//foo/"), "all"));
97 c.all_dependent_configs().push_back(LabelConfigPair(&all));
99 // Direct dependent config.
100 Config direct(setup.settings(), Label(SourceDir("//foo/"), "direct"));
101 c.public_configs().push_back(LabelConfigPair(&direct));
103 ASSERT_TRUE(c.OnResolved(&err));
104 ASSERT_TRUE(b.OnResolved(&err));
105 ASSERT_TRUE(a.OnResolved(&err));
107 // B should have gotten both dependent configs from C.
108 ASSERT_EQ(2u, b.configs().size());
109 EXPECT_EQ(&all, b.configs()[0].ptr);
110 EXPECT_EQ(&direct, b.configs()[1].ptr);
111 ASSERT_EQ(1u, b.all_dependent_configs().size());
112 EXPECT_EQ(&all, b.all_dependent_configs()[0].ptr);
114 // A should have just gotten the "all" dependent config from C.
115 ASSERT_EQ(1u, a.configs().size());
116 EXPECT_EQ(&all, a.configs()[0].ptr);
117 EXPECT_EQ(&all, a.all_dependent_configs()[0].ptr);
119 // Making an an alternate A and B with B forwarding the direct dependents.
120 TestTarget a_fwd(setup, "//foo:a_fwd", Target::EXECUTABLE);
121 TestTarget b_fwd(setup, "//foo:b_fwd", Target::STATIC_LIBRARY);
122 a_fwd.private_deps().push_back(LabelTargetPair(&b_fwd));
123 b_fwd.private_deps().push_back(LabelTargetPair(&c));
124 b_fwd.forward_dependent_configs().push_back(LabelTargetPair(&c));
126 ASSERT_TRUE(b_fwd.OnResolved(&err));
127 ASSERT_TRUE(a_fwd.OnResolved(&err));
129 // A_fwd should now have both configs.
130 ASSERT_EQ(2u, a_fwd.configs().size());
131 EXPECT_EQ(&all, a_fwd.configs()[0].ptr);
132 EXPECT_EQ(&direct, a_fwd.configs()[1].ptr);
133 ASSERT_EQ(1u, a_fwd.all_dependent_configs().size());
134 EXPECT_EQ(&all, a_fwd.all_dependent_configs()[0].ptr);
137 TEST(Target, InheritLibs) {
138 TestWithScope setup;
139 Err err;
141 // Create a dependency chain:
142 // A (executable) -> B (shared lib) -> C (static lib) -> D (source set)
143 TestTarget a(setup, "//foo:a", Target::EXECUTABLE);
144 TestTarget b(setup, "//foo:b", Target::SHARED_LIBRARY);
145 TestTarget c(setup, "//foo:c", Target::STATIC_LIBRARY);
146 TestTarget d(setup, "//foo:d", Target::SOURCE_SET);
147 a.private_deps().push_back(LabelTargetPair(&b));
148 b.private_deps().push_back(LabelTargetPair(&c));
149 c.private_deps().push_back(LabelTargetPair(&d));
151 ASSERT_TRUE(d.OnResolved(&err));
152 ASSERT_TRUE(c.OnResolved(&err));
153 ASSERT_TRUE(b.OnResolved(&err));
154 ASSERT_TRUE(a.OnResolved(&err));
156 // C should have D in its inherited libs.
157 std::vector<const Target*> c_inherited = c.inherited_libraries().GetOrdered();
158 ASSERT_EQ(1u, c_inherited.size());
159 EXPECT_EQ(&d, c_inherited[0]);
161 // B should have C and D in its inherited libs.
162 std::vector<const Target*> b_inherited = b.inherited_libraries().GetOrdered();
163 ASSERT_EQ(2u, b_inherited.size());
164 EXPECT_EQ(&c, b_inherited[0]);
165 EXPECT_EQ(&d, b_inherited[1]);
167 // A should have B in its inherited libs, but not any others (the shared
168 // library will include the static library and source set).
169 std::vector<const Target*> a_inherited = a.inherited_libraries().GetOrdered();
170 ASSERT_EQ(1u, a_inherited.size());
171 EXPECT_EQ(&b, a_inherited[0]);
174 TEST(Target, InheritCompleteStaticLib) {
175 TestWithScope setup;
176 Err err;
178 // Create a dependency chain:
179 // A (executable) -> B (complete static lib) -> C (source set)
180 TestTarget a(setup, "//foo:a", Target::EXECUTABLE);
181 TestTarget b(setup, "//foo:b", Target::STATIC_LIBRARY);
182 b.set_complete_static_lib(true);
183 TestTarget c(setup, "//foo:c", Target::SOURCE_SET);
184 a.public_deps().push_back(LabelTargetPair(&b));
185 b.public_deps().push_back(LabelTargetPair(&c));
187 ASSERT_TRUE(c.OnResolved(&err));
188 ASSERT_TRUE(b.OnResolved(&err));
189 ASSERT_TRUE(a.OnResolved(&err));
191 // B should have C in its inherited libs.
192 std::vector<const Target*> b_inherited = b.inherited_libraries().GetOrdered();
193 ASSERT_EQ(1u, b_inherited.size());
194 EXPECT_EQ(&c, b_inherited[0]);
196 // A should have B in its inherited libs, but not any others (the complete
197 // static library will include the source set).
198 std::vector<const Target*> a_inherited = a.inherited_libraries().GetOrdered();
199 EXPECT_EQ(1u, a_inherited.size());
200 EXPECT_EQ(&b, a_inherited[0]);
203 TEST(Target, InheritCompleteStaticLibNoDirectStaticLibDeps) {
204 TestWithScope setup;
205 Err err;
207 // Create a dependency chain:
208 // A (complete static lib) -> B (static lib)
209 TestTarget a(setup, "//foo:a", Target::STATIC_LIBRARY);
210 a.set_complete_static_lib(true);
211 TestTarget b(setup, "//foo:b", Target::STATIC_LIBRARY);
213 a.public_deps().push_back(LabelTargetPair(&b));
214 ASSERT_TRUE(b.OnResolved(&err));
215 ASSERT_FALSE(a.OnResolved(&err));
218 TEST(Target, InheritCompleteStaticLibNoIheritedStaticLibDeps) {
219 TestWithScope setup;
220 Err err;
222 // Create a dependency chain:
223 // A (complete static lib) -> B (source set) -> C (static lib)
224 TestTarget a(setup, "//foo:a", Target::STATIC_LIBRARY);
225 a.set_complete_static_lib(true);
226 TestTarget b(setup, "//foo:b", Target::SOURCE_SET);
227 TestTarget c(setup, "//foo:c", Target::STATIC_LIBRARY);
229 a.public_deps().push_back(LabelTargetPair(&b));
230 b.public_deps().push_back(LabelTargetPair(&c));
232 ASSERT_TRUE(c.OnResolved(&err));
233 ASSERT_TRUE(b.OnResolved(&err));
234 ASSERT_FALSE(a.OnResolved(&err));
237 TEST(Target, GetComputedOutputName) {
238 TestWithScope setup;
239 Err err;
241 // Basic target with no prefix (executable type tool in the TestWithScope has
242 // no prefix) or output name.
243 TestTarget basic(setup, "//foo:bar", Target::EXECUTABLE);
244 ASSERT_TRUE(basic.OnResolved(&err));
245 EXPECT_EQ("bar", basic.GetComputedOutputName(false));
246 EXPECT_EQ("bar", basic.GetComputedOutputName(true));
248 // Target with no prefix but an output name.
249 TestTarget with_name(setup, "//foo:bar", Target::EXECUTABLE);
250 with_name.set_output_name("myoutput");
251 ASSERT_TRUE(with_name.OnResolved(&err));
252 EXPECT_EQ("myoutput", with_name.GetComputedOutputName(false));
253 EXPECT_EQ("myoutput", with_name.GetComputedOutputName(true));
255 // Target with a "lib" prefix (the static library tool in the TestWithScope
256 // should specify a "lib" output prefix).
257 TestTarget with_prefix(setup, "//foo:bar", Target::STATIC_LIBRARY);
258 ASSERT_TRUE(with_prefix.OnResolved(&err));
259 EXPECT_EQ("bar", with_prefix.GetComputedOutputName(false));
260 EXPECT_EQ("libbar", with_prefix.GetComputedOutputName(true));
262 // Target with a "lib" prefix that already has it applied. The prefix should
263 // not duplicate something already in the target name.
264 TestTarget dup_prefix(setup, "//foo:bar", Target::STATIC_LIBRARY);
265 dup_prefix.set_output_name("libbar");
266 ASSERT_TRUE(dup_prefix.OnResolved(&err));
267 EXPECT_EQ("libbar", dup_prefix.GetComputedOutputName(false));
268 EXPECT_EQ("libbar", dup_prefix.GetComputedOutputName(true));
271 // Test visibility failure case.
272 TEST(Target, VisibilityFails) {
273 TestWithScope setup;
274 Err err;
276 TestTarget b(setup, "//private:b", Target::STATIC_LIBRARY);
277 b.visibility().SetPrivate(b.label().dir());
278 ASSERT_TRUE(b.OnResolved(&err));
280 // Make a target depending on "b". The dependency must have an origin to mark
281 // it as user-set so we check visibility. This check should fail.
282 TestTarget a(setup, "//app:a", Target::EXECUTABLE);
283 a.private_deps().push_back(LabelTargetPair(&b));
284 IdentifierNode origin; // Dummy origin.
285 a.private_deps()[0].origin = &origin;
286 ASSERT_FALSE(a.OnResolved(&err));
289 // Test visibility with a single data_dep.
290 TEST(Target, VisibilityDatadeps) {
291 TestWithScope setup;
292 Err err;
294 TestTarget b(setup, "//public:b", Target::STATIC_LIBRARY);
295 ASSERT_TRUE(b.OnResolved(&err));
297 // Make a target depending on "b". The dependency must have an origin to mark
298 // it as user-set so we check visibility. This check should fail.
299 TestTarget a(setup, "//app:a", Target::EXECUTABLE);
300 a.data_deps().push_back(LabelTargetPair(&b));
301 IdentifierNode origin; // Dummy origin.
302 a.data_deps()[0].origin = &origin;
303 ASSERT_TRUE(a.OnResolved(&err)) << err.help_text();
306 // Tests that A -> Group -> B where the group is visible from A but B isn't,
307 // passes visibility even though the group's deps get expanded into A.
308 TEST(Target, VisibilityGroup) {
309 TestWithScope setup;
310 Err err;
312 IdentifierNode origin; // Dummy origin.
314 // B has private visibility. This lets the group see it since the group is in
315 // the same directory.
316 TestTarget b(setup, "//private:b", Target::STATIC_LIBRARY);
317 b.visibility().SetPrivate(b.label().dir());
318 ASSERT_TRUE(b.OnResolved(&err));
320 // The group has public visibility and depends on b.
321 TestTarget g(setup, "//public:g", Target::GROUP);
322 g.private_deps().push_back(LabelTargetPair(&b));
323 g.private_deps()[0].origin = &origin;
324 ASSERT_TRUE(b.OnResolved(&err));
326 // Make a target depending on "g". This should succeed.
327 TestTarget a(setup, "//app:a", Target::EXECUTABLE);
328 a.private_deps().push_back(LabelTargetPair(&g));
329 a.private_deps()[0].origin = &origin;
330 ASSERT_TRUE(a.OnResolved(&err));
333 // Verifies that only testonly targets can depend on other testonly targets.
334 // Many of the above dependency checking cases covered the non-testonly
335 // case.
336 TEST(Target, Testonly) {
337 TestWithScope setup;
338 Err err;
340 // "testlib" is a test-only library.
341 TestTarget testlib(setup, "//test:testlib", Target::STATIC_LIBRARY);
342 testlib.set_testonly(true);
343 ASSERT_TRUE(testlib.OnResolved(&err));
345 // "test" is a test-only executable depending on testlib, this is OK.
346 TestTarget test(setup, "//test:test", Target::EXECUTABLE);
347 test.set_testonly(true);
348 test.private_deps().push_back(LabelTargetPair(&testlib));
349 ASSERT_TRUE(test.OnResolved(&err));
351 // "product" is a non-test depending on testlib. This should fail.
352 TestTarget product(setup, "//app:product", Target::EXECUTABLE);
353 product.set_testonly(false);
354 product.private_deps().push_back(LabelTargetPair(&testlib));
355 ASSERT_FALSE(product.OnResolved(&err));
358 TEST(Target, PublicConfigs) {
359 TestWithScope setup;
360 Err err;
362 Label pub_config_label(SourceDir("//a/"), "pubconfig");
363 Config pub_config(setup.settings(), pub_config_label);
365 // This is the destination target that has a public config.
366 TestTarget dest(setup, "//a:a", Target::SOURCE_SET);
367 dest.public_configs().push_back(LabelConfigPair(&pub_config));
368 ASSERT_TRUE(dest.OnResolved(&err));
370 // This target has a public dependency on dest.
371 TestTarget pub(setup, "//a:pub", Target::SOURCE_SET);
372 pub.public_deps().push_back(LabelTargetPair(&dest));
373 ASSERT_TRUE(pub.OnResolved(&err));
375 // Depending on the target with the public dependency should forward dest's
376 // to the current target.
377 TestTarget dep_on_pub(setup, "//a:dop", Target::SOURCE_SET);
378 dep_on_pub.private_deps().push_back(LabelTargetPair(&pub));
379 ASSERT_TRUE(dep_on_pub.OnResolved(&err));
380 ASSERT_EQ(1u, dep_on_pub.configs().size());
381 EXPECT_EQ(&pub_config, dep_on_pub.configs()[0].ptr);
383 // This target has a private dependency on dest for forwards configs.
384 TestTarget forward(setup, "//a:f", Target::SOURCE_SET);
385 forward.private_deps().push_back(LabelTargetPair(&dest));
386 forward.forward_dependent_configs().push_back(LabelTargetPair(&dest));
387 ASSERT_TRUE(forward.OnResolved(&err));
389 // Depending on the forward target should apply the config.
390 TestTarget dep_on_forward(setup, "//a:dof", Target::SOURCE_SET);
391 dep_on_forward.private_deps().push_back(LabelTargetPair(&forward));
392 ASSERT_TRUE(dep_on_forward.OnResolved(&err));
393 ASSERT_EQ(1u, dep_on_forward.configs().size());
394 EXPECT_EQ(&pub_config, dep_on_forward.configs()[0].ptr);
397 // Tests that different link/depend outputs work for solink tools.
398 TEST(Target, LinkAndDepOutputs) {
399 TestWithScope setup;
400 Err err;
402 Toolchain toolchain(setup.settings(), Label(SourceDir("//tc/"), "tc"));
404 scoped_ptr<Tool> solink_tool(new Tool());
405 solink_tool->set_output_prefix("lib");
406 solink_tool->set_default_output_extension(".so");
408 const char kLinkPattern[] =
409 "{{root_out_dir}}/{{target_output_name}}{{output_extension}}";
410 SubstitutionPattern link_output = SubstitutionPattern::MakeForTest(
411 kLinkPattern);
412 solink_tool->set_link_output(link_output);
414 const char kDependPattern[] =
415 "{{root_out_dir}}/{{target_output_name}}{{output_extension}}.TOC";
416 SubstitutionPattern depend_output = SubstitutionPattern::MakeForTest(
417 kDependPattern);
418 solink_tool->set_depend_output(depend_output);
420 solink_tool->set_outputs(SubstitutionList::MakeForTest(
421 kLinkPattern, kDependPattern));
423 toolchain.SetTool(Toolchain::TYPE_SOLINK, solink_tool.Pass());
425 Target target(setup.settings(), Label(SourceDir("//a/"), "a"));
426 target.set_output_type(Target::SHARED_LIBRARY);
427 target.SetToolchain(&toolchain);
428 ASSERT_TRUE(target.OnResolved(&err));
430 EXPECT_EQ("./liba.so", target.link_output_file().value());
431 EXPECT_EQ("./liba.so.TOC", target.dependency_output_file().value());
434 // Shared libraries should be inherited across public shared liobrary
435 // boundaries.
436 TEST(Target, SharedInheritance) {
437 TestWithScope setup;
438 Err err;
440 // Create two leaf shared libraries.
441 TestTarget pub(setup, "//foo:pub", Target::SHARED_LIBRARY);
442 ASSERT_TRUE(pub.OnResolved(&err));
444 TestTarget priv(setup, "//foo:priv", Target::SHARED_LIBRARY);
445 ASSERT_TRUE(priv.OnResolved(&err));
447 // Intermediate shared library with the leaf shared libraries as
448 // dependencies, one public, one private.
449 TestTarget inter(setup, "//foo:inter", Target::SHARED_LIBRARY);
450 inter.public_deps().push_back(LabelTargetPair(&pub));
451 inter.private_deps().push_back(LabelTargetPair(&priv));
452 ASSERT_TRUE(inter.OnResolved(&err));
454 // The intermediate shared library should have both "pub" and "priv" in its
455 // inherited libraries.
456 std::vector<const Target*> inter_inherited =
457 inter.inherited_libraries().GetOrdered();
458 ASSERT_EQ(2u, inter_inherited.size());
459 EXPECT_EQ(&pub, inter_inherited[0]);
460 EXPECT_EQ(&priv, inter_inherited[1]);
462 // Make a toplevel executable target depending on the intermediate one.
463 TestTarget exe(setup, "//foo:exe", Target::SHARED_LIBRARY);
464 exe.private_deps().push_back(LabelTargetPair(&inter));
465 ASSERT_TRUE(exe.OnResolved(&err));
467 // The exe's inherited libraries should be "inter" (because it depended
468 // directly on it) and "pub" (because inter depended publicly on it).
469 std::vector<const Target*> exe_inherited =
470 exe.inherited_libraries().GetOrdered();
471 ASSERT_EQ(2u, exe_inherited.size());
472 EXPECT_EQ(&inter, exe_inherited[0]);
473 EXPECT_EQ(&pub, exe_inherited[1]);
476 TEST(Target, GeneratedInputs) {
477 Scheduler scheduler;
478 TestWithScope setup;
479 Err err;
481 SourceFile generated_file("//out/Debug/generated.cc");
483 // This target has a generated input and no dependency makes it.
484 TestTarget non_existent_generator(setup, "//foo:non_existent_generator",
485 Target::EXECUTABLE);
486 non_existent_generator.sources().push_back(generated_file);
487 EXPECT_TRUE(non_existent_generator.OnResolved(&err)) << err.message();
488 AssertSchedulerHasOneUnknownFileMatching(&non_existent_generator,
489 generated_file);
490 scheduler.ClearUnknownGeneratedInputsAndWrittenFiles();
492 // Make a target that generates the file.
493 TestTarget generator(setup, "//foo:generator", Target::ACTION);
494 generator.action_values().outputs() =
495 SubstitutionList::MakeForTest(generated_file.value().c_str());
496 err = Err();
497 EXPECT_TRUE(generator.OnResolved(&err)) << err.message();
499 // A target that depends on the generator that uses the file as a source
500 // should be OK. This uses a private dep (will be used later).
501 TestTarget existent_generator(setup, "//foo:existent_generator",
502 Target::SHARED_LIBRARY);
503 existent_generator.sources().push_back(generated_file);
504 existent_generator.private_deps().push_back(LabelTargetPair(&generator));
505 EXPECT_TRUE(existent_generator.OnResolved(&err)) << err.message();
506 EXPECT_TRUE(scheduler.GetUnknownGeneratedInputs().empty());
508 // A target that depends on the previous one should *not* be allowed to
509 // use the generated file, because existent_generator used private deps.
510 // This is:
511 // indirect_private --> existent_generator --[private]--> generator
512 TestTarget indirect_private(setup, "//foo:indirect_private",
513 Target::EXECUTABLE);
514 indirect_private.sources().push_back(generated_file);
515 indirect_private.public_deps().push_back(
516 LabelTargetPair(&existent_generator));
517 EXPECT_TRUE(indirect_private.OnResolved(&err));
518 AssertSchedulerHasOneUnknownFileMatching(&indirect_private, generated_file);
519 scheduler.ClearUnknownGeneratedInputsAndWrittenFiles();
521 // Now make a chain like the above but with all public deps, it should be OK.
522 TestTarget existent_public(setup, "//foo:existent_public",
523 Target::SHARED_LIBRARY);
524 existent_public.public_deps().push_back(LabelTargetPair(&generator));
525 EXPECT_TRUE(existent_public.OnResolved(&err)) << err.message();
526 TestTarget indirect_public(setup, "//foo:indirect_public",
527 Target::EXECUTABLE);
528 indirect_public.sources().push_back(generated_file);
529 indirect_public.public_deps().push_back(LabelTargetPair(&existent_public));
530 EXPECT_TRUE(indirect_public.OnResolved(&err)) << err.message();
531 EXPECT_TRUE(scheduler.GetUnknownGeneratedInputs().empty());
534 // This is sort of a Scheduler test, but is related to the above test more.
535 TEST(Target, WriteFileGeneratedInputs) {
536 Scheduler scheduler;
537 TestWithScope setup;
538 Err err;
540 SourceFile generated_file("//out/Debug/generated.data");
542 // This target has a generated input and no dependency makes it.
543 TestTarget non_existent_generator(setup, "//foo:non_existent_generator",
544 Target::EXECUTABLE);
545 non_existent_generator.sources().push_back(generated_file);
546 EXPECT_TRUE(non_existent_generator.OnResolved(&err));
547 AssertSchedulerHasOneUnknownFileMatching(&non_existent_generator,
548 generated_file);
549 scheduler.ClearUnknownGeneratedInputsAndWrittenFiles();
551 // This target has a generated file and we've decared we write it.
552 TestTarget existent_generator(setup, "//foo:existent_generator",
553 Target::EXECUTABLE);
554 existent_generator.sources().push_back(generated_file);
555 EXPECT_TRUE(existent_generator.OnResolved(&err));
556 scheduler.AddWrittenFile(generated_file);
558 // Should be OK.
559 EXPECT_TRUE(scheduler.GetUnknownGeneratedInputs().empty());
562 TEST(Target, ResolvePrecompiledHeaders) {
563 TestWithScope setup;
564 Err err;
566 Target target(setup.settings(), Label(SourceDir("//foo/"), "bar"));
568 // Target with no settings, no configs, should be a no-op.
569 EXPECT_TRUE(target.ResolvePrecompiledHeaders(&err));
571 // Config with PCH values.
572 Config config_1(setup.settings(), Label(SourceDir("//foo/"), "c1"));
573 std::string pch_1("pch.h");
574 SourceFile pcs_1("//pcs.cc");
575 config_1.config_values().set_precompiled_header(pch_1);
576 config_1.config_values().set_precompiled_source(pcs_1);
577 target.configs().push_back(LabelConfigPair(&config_1));
579 // No PCH info specified on target, but the config specifies one, the
580 // values should get copied to the target.
581 EXPECT_TRUE(target.ResolvePrecompiledHeaders(&err));
582 EXPECT_EQ(pch_1, target.config_values().precompiled_header());
583 EXPECT_TRUE(target.config_values().precompiled_source() == pcs_1);
585 // Now both target and config have matching PCH values. Resolving again
586 // should be a no-op since they all match.
587 EXPECT_TRUE(target.ResolvePrecompiledHeaders(&err));
588 EXPECT_TRUE(target.config_values().precompiled_header() == pch_1);
589 EXPECT_TRUE(target.config_values().precompiled_source() == pcs_1);
591 // Second config with different PCH values.
592 Config config_2(setup.settings(), Label(SourceDir("//foo/"), "c2"));
593 std::string pch_2("pch2.h");
594 SourceFile pcs_2("//pcs2.cc");
595 config_2.config_values().set_precompiled_header(pch_2);
596 config_2.config_values().set_precompiled_source(pcs_2);
597 target.configs().push_back(LabelConfigPair(&config_2));
599 // This should be an error since they don't match.
600 EXPECT_FALSE(target.ResolvePrecompiledHeaders(&err));
602 // Make sure the proper labels are blamed.
603 EXPECT_EQ(
604 "The target //foo:bar\n"
605 "has conflicting precompiled header settings.\n"
606 "\n"
607 "From //foo:bar\n"
608 " header: pch.h\n"
609 " source: //pcs.cc\n"
610 "\n"
611 "From //foo:c2\n"
612 " header: pch2.h\n"
613 " source: //pcs2.cc",
614 err.help_text());