• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.
4 
5 #include "gn/target.h"
6 
7 #include <memory>
8 #include <utility>
9 
10 #include "gn/build_settings.h"
11 #include "gn/config.h"
12 #include "gn/resolved_target_data.h"
13 #include "gn/scheduler.h"
14 #include "gn/settings.h"
15 #include "gn/test_with_scheduler.h"
16 #include "gn/test_with_scope.h"
17 #include "gn/toolchain.h"
18 #include "util/test/test.h"
19 
20 namespace {
21 
22 // Asserts that the current global scheduler has a single unknown generated
23 // file with the given name from the given target.
AssertSchedulerHasOneUnknownFileMatching(const Target * target,const SourceFile & file)24 void AssertSchedulerHasOneUnknownFileMatching(const Target* target,
25                                               const SourceFile& file) {
26   auto unknown = g_scheduler->GetUnknownGeneratedInputs();
27   ASSERT_EQ(1u, unknown.size());  // Should be one unknown file.
28   auto found = unknown.find(file);
29   ASSERT_TRUE(found != unknown.end()) << file.value();
30   EXPECT_TRUE(target == found->second)
31       << "Target doesn't match. Expected\n  "
32       << target->label().GetUserVisibleName(false) << "\nBut got\n  "
33       << found->second->label().GetUserVisibleName(false);
34 }
35 
36 }  // namespace
37 
38 using TargetTest = TestWithScheduler;
39 
40 // Test all_dependent_configs and public_config inheritance.
TEST_F(TargetTest,DependentConfigs)41 TEST_F(TargetTest, DependentConfigs) {
42   TestWithScope setup;
43   Err err;
44 
45   // Set up a dependency chain of a -> b -> c
46   TestTarget a(setup, "//foo:a", Target::EXECUTABLE);
47   TestTarget b(setup, "//foo:b", Target::STATIC_LIBRARY);
48   TestTarget c(setup, "//foo:c", Target::STATIC_LIBRARY);
49   a.private_deps().push_back(LabelTargetPair(&b));
50   b.private_deps().push_back(LabelTargetPair(&c));
51 
52   // Normal non-inherited config.
53   Config config(setup.settings(), Label(SourceDir("//foo/"), "config"));
54   config.visibility().SetPublic();
55   ASSERT_TRUE(config.OnResolved(&err));
56   c.configs().push_back(LabelConfigPair(&config));
57 
58   // All dependent config.
59   Config all(setup.settings(), Label(SourceDir("//foo/"), "all"));
60   all.visibility().SetPublic();
61   ASSERT_TRUE(all.OnResolved(&err));
62   c.all_dependent_configs().push_back(LabelConfigPair(&all));
63 
64   // Direct dependent config.
65   Config direct(setup.settings(), Label(SourceDir("//foo/"), "direct"));
66   direct.visibility().SetPublic();
67   ASSERT_TRUE(direct.OnResolved(&err));
68   c.public_configs().push_back(LabelConfigPair(&direct));
69 
70   ASSERT_TRUE(c.OnResolved(&err));
71   ASSERT_TRUE(b.OnResolved(&err));
72   ASSERT_TRUE(a.OnResolved(&err));
73 
74   // B should have gotten both dependent configs from C.
75   ASSERT_EQ(2u, b.configs().size());
76   EXPECT_EQ(&all, b.configs()[0].ptr);
77   EXPECT_EQ(&direct, b.configs()[1].ptr);
78   ASSERT_EQ(1u, b.all_dependent_configs().size());
79   EXPECT_EQ(&all, b.all_dependent_configs()[0].ptr);
80 
81   // A should have just gotten the "all" dependent config from C.
82   ASSERT_EQ(1u, a.configs().size());
83   EXPECT_EQ(&all, a.configs()[0].ptr);
84   EXPECT_EQ(&all, a.all_dependent_configs()[0].ptr);
85 
86   // Making an an alternate A and B with B forwarding the direct dependents.
87   TestTarget a_fwd(setup, "//foo:a_fwd", Target::EXECUTABLE);
88   TestTarget b_fwd(setup, "//foo:b_fwd", Target::STATIC_LIBRARY);
89   a_fwd.private_deps().push_back(LabelTargetPair(&b_fwd));
90   b_fwd.private_deps().push_back(LabelTargetPair(&c));
91 
92   ASSERT_TRUE(b_fwd.OnResolved(&err));
93   ASSERT_TRUE(a_fwd.OnResolved(&err));
94 
95   // A_fwd should now have both configs.
96   ASSERT_EQ(1u, a_fwd.configs().size());
97   EXPECT_EQ(&all, a_fwd.configs()[0].ptr);
98   ASSERT_EQ(1u, a_fwd.all_dependent_configs().size());
99   EXPECT_EQ(&all, a_fwd.all_dependent_configs()[0].ptr);
100 }
101 
102 // Tests that dependent configs don't propagate between toolchains.
TEST_F(TargetTest,NoDependentConfigsBetweenToolchains)103 TEST_F(TargetTest, NoDependentConfigsBetweenToolchains) {
104   TestWithScope setup;
105   Err err;
106 
107   // Create another toolchain.
108   Toolchain other_toolchain(setup.settings(),
109                             Label(SourceDir("//other/"), "toolchain"));
110   TestWithScope::SetupToolchain(&other_toolchain);
111 
112   // Set up a dependency chain of |a| -> |b| -> |c| where |a| has a different
113   // toolchain.
114   Target a(setup.settings(),
115            Label(SourceDir("//foo/"), "a", other_toolchain.label().dir(),
116                  other_toolchain.label().name()));
117   a.set_output_type(Target::EXECUTABLE);
118   EXPECT_TRUE(a.SetToolchain(&other_toolchain, &err));
119   TestTarget b(setup, "//foo:b", Target::EXECUTABLE);
120   TestTarget c(setup, "//foo:c", Target::SOURCE_SET);
121   a.private_deps().push_back(LabelTargetPair(&b));
122   b.private_deps().push_back(LabelTargetPair(&c));
123 
124   // All dependent config.
125   Config all_dependent(setup.settings(), Label(SourceDir("//foo/"), "all"));
126   all_dependent.visibility().SetPublic();
127   ASSERT_TRUE(all_dependent.OnResolved(&err));
128   c.all_dependent_configs().push_back(LabelConfigPair(&all_dependent));
129 
130   // Public config.
131   Config public_config(setup.settings(), Label(SourceDir("//foo/"), "public"));
132   public_config.visibility().SetPublic();
133   ASSERT_TRUE(public_config.OnResolved(&err));
134   c.public_configs().push_back(LabelConfigPair(&public_config));
135 
136   // Another public config.
137   Config public_config2(setup.settings(),
138                         Label(SourceDir("//foo/"), "public2"));
139   public_config2.visibility().SetPublic();
140   ASSERT_TRUE(public_config2.OnResolved(&err));
141   b.public_configs().push_back(LabelConfigPair(&public_config2));
142 
143   ASSERT_TRUE(c.OnResolved(&err));
144   ASSERT_TRUE(b.OnResolved(&err));
145   ASSERT_TRUE(a.OnResolved(&err));
146 
147   // B should have gotten the configs from C.
148   ASSERT_EQ(3u, b.configs().size());
149   EXPECT_EQ(&public_config2, b.configs()[0].ptr);
150   EXPECT_EQ(&all_dependent, b.configs()[1].ptr);
151   EXPECT_EQ(&public_config, b.configs()[2].ptr);
152   ASSERT_EQ(1u, b.all_dependent_configs().size());
153   EXPECT_EQ(&all_dependent, b.all_dependent_configs()[0].ptr);
154 
155   // A should not have gotten any configs from B or C.
156   ASSERT_EQ(0u, a.configs().size());
157   ASSERT_EQ(0u, a.all_dependent_configs().size());
158 }
159 
160 // Tests that dependent configs propagate between toolchains if
161 // propagates_configs is set.
TEST_F(TargetTest,DependentConfigsBetweenToolchainsWhenSet)162 TEST_F(TargetTest, DependentConfigsBetweenToolchainsWhenSet) {
163   TestWithScope setup;
164   Err err;
165 
166   // Create another toolchain.
167   Toolchain other_toolchain(setup.settings(),
168                             Label(SourceDir("//other/"), "toolchain"));
169   TestWithScope::SetupToolchain(&other_toolchain);
170   other_toolchain.set_propagates_configs(true);
171 
172   // Set up a dependency chain of |a| -> |b| where |b| has a different
173   // toolchain (with propagate_configs set).
174   TestTarget a(setup, "//foo:a", Target::EXECUTABLE);
175   Target b(setup.settings(),
176            Label(SourceDir("//foo/"), "b", other_toolchain.label().dir(),
177                  other_toolchain.label().name()));
178   b.visibility().SetPublic();
179   b.set_output_type(Target::SHARED_LIBRARY);
180   EXPECT_TRUE(b.SetToolchain(&other_toolchain, &err));
181   a.private_deps().push_back(LabelTargetPair(&b));
182 
183   // All dependent config.
184   Config all_dependent(setup.settings(), Label(SourceDir("//foo/"), "all"));
185   all_dependent.visibility().SetPublic();
186   ASSERT_TRUE(all_dependent.OnResolved(&err));
187   b.all_dependent_configs().push_back(LabelConfigPair(&all_dependent));
188 
189   // Public config.
190   Config public_config(setup.settings(), Label(SourceDir("//foo/"), "public"));
191   public_config.visibility().SetPublic();
192   ASSERT_TRUE(public_config.OnResolved(&err));
193   b.public_configs().push_back(LabelConfigPair(&public_config));
194 
195   ASSERT_TRUE(b.OnResolved(&err));
196   ASSERT_TRUE(a.OnResolved(&err));
197 
198   // A should have gotten the configs from B.
199   ASSERT_EQ(2u, a.configs().size());
200   EXPECT_EQ(&all_dependent, a.configs()[0].ptr);
201   EXPECT_EQ(&public_config, a.configs()[1].ptr);
202   ASSERT_EQ(1u, a.all_dependent_configs().size());
203   EXPECT_EQ(&all_dependent, a.all_dependent_configs()[0].ptr);
204 }
205 
TEST_F(TargetTest,GetComputedOutputName)206 TEST_F(TargetTest, GetComputedOutputName) {
207   TestWithScope setup;
208   Err err;
209 
210   // Basic target with no prefix (executable type tool in the TestWithScope has
211   // no prefix) or output name.
212   TestTarget basic(setup, "//foo:bar", Target::EXECUTABLE);
213   ASSERT_TRUE(basic.OnResolved(&err));
214   EXPECT_EQ("bar", basic.GetComputedOutputName());
215 
216   // Target with no prefix but an output name.
217   TestTarget with_name(setup, "//foo:bar", Target::EXECUTABLE);
218   with_name.set_output_name("myoutput");
219   ASSERT_TRUE(with_name.OnResolved(&err));
220   EXPECT_EQ("myoutput", with_name.GetComputedOutputName());
221 
222   // Target with a "lib" prefix (the static library tool in the TestWithScope
223   // should specify a "lib" output prefix).
224   TestTarget with_prefix(setup, "//foo:bar", Target::STATIC_LIBRARY);
225   ASSERT_TRUE(with_prefix.OnResolved(&err));
226   EXPECT_EQ("libbar", with_prefix.GetComputedOutputName());
227 
228   // Target with a "lib" prefix that already has it applied. The prefix should
229   // not duplicate something already in the target name.
230   TestTarget dup_prefix(setup, "//foo:bar", Target::STATIC_LIBRARY);
231   dup_prefix.set_output_name("libbar");
232   ASSERT_TRUE(dup_prefix.OnResolved(&err));
233   EXPECT_EQ("libbar", dup_prefix.GetComputedOutputName());
234 
235   // Target with an output prefix override should not have a prefix.
236   TestTarget override_prefix(setup, "//foo:bar", Target::SHARED_LIBRARY);
237   override_prefix.set_output_prefix_override(true);
238   ASSERT_TRUE(dup_prefix.OnResolved(&err));
239   EXPECT_EQ("bar", override_prefix.GetComputedOutputName());
240 }
241 
242 // Test visibility failure case.
TEST_F(TargetTest,VisibilityFails)243 TEST_F(TargetTest, VisibilityFails) {
244   TestWithScope setup;
245   Err err;
246 
247   TestTarget b(setup, "//private:b", Target::STATIC_LIBRARY);
248   b.visibility().SetPrivate(b.label().dir());
249   ASSERT_TRUE(b.OnResolved(&err));
250 
251   // Make a target depending on "b". The dependency must have an origin to mark
252   // it as user-set so we check visibility. This check should fail.
253   TestTarget a(setup, "//app:a", Target::EXECUTABLE);
254   a.private_deps().push_back(LabelTargetPair(&b));
255   IdentifierNode origin;  // Dummy origin.
256   a.private_deps()[0].origin = &origin;
257   ASSERT_FALSE(a.OnResolved(&err));
258 }
259 
260 // Test config visibility failure cases.
TEST_F(TargetTest,VisibilityConfigFails)261 TEST_F(TargetTest, VisibilityConfigFails) {
262   TestWithScope setup;
263   Err err;
264 
265   Label config_label(SourceDir("//a/"), "config");
266   Config config(setup.settings(), config_label);
267   config.visibility().SetPrivate(config.label().dir());
268   ASSERT_TRUE(config.OnResolved(&err));
269 
270   // Make a target using configs. This should fail.
271   TestTarget a(setup, "//app:a", Target::EXECUTABLE);
272   a.configs().push_back(LabelConfigPair(&config));
273   ASSERT_FALSE(a.OnResolved(&err));
274 
275   // A target using public_configs should also fail.
276   TestTarget b(setup, "//app:b", Target::EXECUTABLE);
277   b.public_configs().push_back(LabelConfigPair(&config));
278   ASSERT_FALSE(b.OnResolved(&err));
279 
280   // A target using all_dependent_configs should fail as well.
281   TestTarget c(setup, "//app:c", Target::EXECUTABLE);
282   c.all_dependent_configs().push_back(LabelConfigPair(&config));
283   ASSERT_FALSE(c.OnResolved(&err));
284 }
285 
286 // Test Config -> Group -> A where the config is group is visible from A but
287 // the config isn't, and the config is visible from the group.
TEST_F(TargetTest,VisibilityConfigGroup)288 TEST_F(TargetTest, VisibilityConfigGroup) {
289   TestWithScope setup;
290   Err err;
291 
292   Label config_label(SourceDir("//a/"), "config");
293   Config config(setup.settings(), config_label);
294   config.visibility().SetPrivate(config.label().dir());
295   ASSERT_TRUE(config.OnResolved(&err));
296 
297   // Make a target using the config in the same directory.
298   TestTarget a(setup, "//a:a", Target::GROUP);
299   a.public_configs().push_back(LabelConfigPair(&config));
300   ASSERT_TRUE(a.OnResolved(&err));
301 
302   // A target depending on a should be okay.
303   TestTarget b(setup, "//app:b", Target::EXECUTABLE);
304   b.private_deps().push_back(LabelTargetPair(&a));
305   ASSERT_TRUE(b.OnResolved(&err));
306 }
307 
308 // Test visibility with a single data_dep.
TEST_F(TargetTest,VisibilityDatadeps)309 TEST_F(TargetTest, VisibilityDatadeps) {
310   TestWithScope setup;
311   Err err;
312 
313   TestTarget b(setup, "//public:b", Target::STATIC_LIBRARY);
314   ASSERT_TRUE(b.OnResolved(&err));
315 
316   // Make a target depending on "b". The dependency must have an origin to mark
317   // it as user-set so we check visibility. This check should fail.
318   TestTarget a(setup, "//app:a", Target::EXECUTABLE);
319   a.data_deps().push_back(LabelTargetPair(&b));
320   IdentifierNode origin;  // Dummy origin.
321   a.data_deps()[0].origin = &origin;
322   ASSERT_TRUE(a.OnResolved(&err)) << err.help_text();
323 }
324 
325 // Tests that A -> Group -> B where the group is visible from A but B isn't,
326 // passes visibility even though the group's deps get expanded into A.
TEST_F(TargetTest,VisibilityGroup)327 TEST_F(TargetTest, VisibilityGroup) {
328   TestWithScope setup;
329   Err err;
330 
331   IdentifierNode origin;  // Dummy origin.
332 
333   // B has private visibility. This lets the group see it since the group is in
334   // the same directory.
335   TestTarget b(setup, "//private:b", Target::STATIC_LIBRARY);
336   b.visibility().SetPrivate(b.label().dir());
337   ASSERT_TRUE(b.OnResolved(&err));
338 
339   // The group has public visibility and depends on b.
340   TestTarget g(setup, "//public:g", Target::GROUP);
341   g.private_deps().push_back(LabelTargetPair(&b));
342   g.private_deps()[0].origin = &origin;
343   ASSERT_TRUE(b.OnResolved(&err));
344 
345   // Make a target depending on "g". This should succeed.
346   TestTarget a(setup, "//app:a", Target::EXECUTABLE);
347   a.private_deps().push_back(LabelTargetPair(&g));
348   a.private_deps()[0].origin = &origin;
349   ASSERT_TRUE(a.OnResolved(&err));
350 }
351 
352 // Verifies that only testonly targets can depend on other testonly targets.
353 // Many of the above dependency checking cases covered the non-testonly
354 // case.
TEST_F(TargetTest,Testonly)355 TEST_F(TargetTest, Testonly) {
356   TestWithScope setup;
357   Err err;
358 
359   // "testlib" is a test-only library.
360   TestTarget testlib(setup, "//test:testlib", Target::STATIC_LIBRARY);
361   testlib.set_testonly(true);
362   ASSERT_TRUE(testlib.OnResolved(&err));
363 
364   // "test" is a test-only executable depending on testlib, this is OK.
365   TestTarget test(setup, "//test:test", Target::EXECUTABLE);
366   test.set_testonly(true);
367   test.private_deps().push_back(LabelTargetPair(&testlib));
368   ASSERT_TRUE(test.OnResolved(&err));
369 
370   // "product" is a non-test depending on testlib. This should fail.
371   TestTarget product(setup, "//app:product", Target::EXECUTABLE);
372   product.set_testonly(false);
373   product.private_deps().push_back(LabelTargetPair(&testlib));
374   ASSERT_FALSE(product.OnResolved(&err));
375 }
376 
377 // Configs can be testonly too.
378 // Repeat the testonly test with a config.
TEST_F(TargetTest,TestonlyConfig)379 TEST_F(TargetTest, TestonlyConfig) {
380   TestWithScope setup;
381   Err err;
382 
383   // "testconfig" is a test-only config.
384   Config testconfig(setup.settings(), Label(SourceDir("//test/"), "config"));
385   testconfig.set_testonly(true);
386   testconfig.visibility().SetPublic();
387   ASSERT_TRUE(testconfig.OnResolved(&err));
388 
389   // "test" is a test-only executable that uses testconfig, this is OK.
390   TestTarget test(setup, "//test:test", Target::EXECUTABLE);
391   test.set_testonly(true);
392   test.configs().push_back(LabelConfigPair(&testconfig));
393   ASSERT_TRUE(test.OnResolved(&err));
394 
395   // "product" is a non-test that uses testconfig. This should fail.
396   TestTarget product(setup, "//app:product", Target::EXECUTABLE);
397   product.set_testonly(false);
398   product.configs().push_back(LabelConfigPair(&testconfig));
399   ASSERT_FALSE(product.OnResolved(&err));
400 }
401 
TEST_F(TargetTest,PublicConfigs)402 TEST_F(TargetTest, PublicConfigs) {
403   TestWithScope setup;
404   Err err;
405 
406   Label pub_config_label(SourceDir("//a/"), "pubconfig");
407   Config pub_config(setup.settings(), pub_config_label);
408   pub_config.visibility().SetPublic();
409   LibFile lib_name("testlib");
410   pub_config.own_values().libs().push_back(lib_name);
411   ASSERT_TRUE(pub_config.OnResolved(&err));
412 
413   // This is the destination target that has a public config.
414   TestTarget dest(setup, "//a:a", Target::SOURCE_SET);
415   dest.public_configs().push_back(LabelConfigPair(&pub_config));
416   ASSERT_TRUE(dest.OnResolved(&err));
417 
418   // This target has a public dependency on dest.
419   TestTarget pub(setup, "//a:pub", Target::SOURCE_SET);
420   pub.public_deps().push_back(LabelTargetPair(&dest));
421   ASSERT_TRUE(pub.OnResolved(&err));
422 
423   // Depending on the target with the public dependency should forward dest's
424   // to the current target.
425   TestTarget dep_on_pub(setup, "//a:dop", Target::SOURCE_SET);
426   dep_on_pub.private_deps().push_back(LabelTargetPair(&pub));
427   ASSERT_TRUE(dep_on_pub.OnResolved(&err));
428   ASSERT_EQ(1u, dep_on_pub.configs().size());
429   EXPECT_EQ(&pub_config, dep_on_pub.configs()[0].ptr);
430 
431   // Libs have special handling, check that they were forwarded from the
432   // public config to all_libs.
433   ResolvedTargetData resolved;
434   const auto& dep_on_pub_all_libs = resolved.GetLinkedLibraries(&dep_on_pub);
435   ASSERT_EQ(1u, dep_on_pub_all_libs.size());
436   ASSERT_EQ(lib_name, dep_on_pub_all_libs[0]);
437 
438   // This target has a private dependency on dest for forwards configs.
439   TestTarget forward(setup, "//a:f", Target::SOURCE_SET);
440   forward.private_deps().push_back(LabelTargetPair(&dest));
441   ASSERT_TRUE(forward.OnResolved(&err));
442 }
443 
444 // Tests that configs are ordered properly between local and pulled ones.
TEST_F(TargetTest,ConfigOrdering)445 TEST_F(TargetTest, ConfigOrdering) {
446   TestWithScope setup;
447   Err err;
448 
449   // Make Dep1. It has all_dependent_configs and public_configs.
450   TestTarget dep1(setup, "//:dep1", Target::SOURCE_SET);
451   Label dep1_all_config_label(SourceDir("//"), "dep1_all_config");
452   Config dep1_all_config(setup.settings(), dep1_all_config_label);
453   dep1_all_config.visibility().SetPublic();
454   ASSERT_TRUE(dep1_all_config.OnResolved(&err));
455   dep1.all_dependent_configs().push_back(LabelConfigPair(&dep1_all_config));
456 
457   Label dep1_public_config_label(SourceDir("//"), "dep1_public_config");
458   Config dep1_public_config(setup.settings(), dep1_public_config_label);
459   dep1_public_config.visibility().SetPublic();
460   ASSERT_TRUE(dep1_public_config.OnResolved(&err));
461   dep1.public_configs().push_back(LabelConfigPair(&dep1_public_config));
462   ASSERT_TRUE(dep1.OnResolved(&err));
463 
464   // Make Dep2 with the same structure.
465   TestTarget dep2(setup, "//:dep2", Target::SOURCE_SET);
466   Label dep2_all_config_label(SourceDir("//"), "dep2_all_config");
467   Config dep2_all_config(setup.settings(), dep2_all_config_label);
468   dep2_all_config.visibility().SetPublic();
469   ASSERT_TRUE(dep2_all_config.OnResolved(&err));
470   dep2.all_dependent_configs().push_back(LabelConfigPair(&dep2_all_config));
471 
472   Label dep2_public_config_label(SourceDir("//"), "dep2_public_config");
473   Config dep2_public_config(setup.settings(), dep2_public_config_label);
474   dep2_public_config.visibility().SetPublic();
475   ASSERT_TRUE(dep2_public_config.OnResolved(&err));
476   dep2.public_configs().push_back(LabelConfigPair(&dep2_public_config));
477   ASSERT_TRUE(dep2.OnResolved(&err));
478 
479   // This target depends on both previous targets.
480   TestTarget target(setup, "//:foo", Target::SOURCE_SET);
481   target.private_deps().push_back(LabelTargetPair(&dep1));
482   target.private_deps().push_back(LabelTargetPair(&dep2));
483 
484   // It also has a private and public config.
485   Label public_config_label(SourceDir("//"), "public");
486   Config public_config(setup.settings(), public_config_label);
487   public_config.visibility().SetPublic();
488   ASSERT_TRUE(public_config.OnResolved(&err));
489   target.public_configs().push_back(LabelConfigPair(&public_config));
490 
491   Label private_config_label(SourceDir("//"), "private");
492   Config private_config(setup.settings(), private_config_label);
493   private_config.visibility().SetPublic();
494   ASSERT_TRUE(private_config.OnResolved(&err));
495   target.configs().push_back(LabelConfigPair(&private_config));
496 
497   // Resolve to get the computed list of configs applying.
498   ASSERT_TRUE(target.OnResolved(&err));
499   const auto& computed = target.configs();
500 
501   // Order should be:
502   // 1. local private
503   // 2. local public
504   // 3. inherited all dependent
505   // 4. inherited public
506   ASSERT_EQ(6u, computed.size());
507   EXPECT_EQ(private_config_label, computed[0].label);
508   EXPECT_EQ(public_config_label, computed[1].label);
509   EXPECT_EQ(dep1_all_config_label, computed[2].label);
510   EXPECT_EQ(dep2_all_config_label, computed[3].label);
511   EXPECT_EQ(dep1_public_config_label, computed[4].label);
512   EXPECT_EQ(dep2_public_config_label, computed[5].label);
513 }
514 
515 // Tests that different link/depend outputs work for solink tools.
TEST_F(TargetTest,LinkAndDepOutputs)516 TEST_F(TargetTest, LinkAndDepOutputs) {
517   TestWithScope setup;
518   Err err;
519 
520   Toolchain toolchain(setup.settings(), Label(SourceDir("//tc/"), "tc"));
521 
522   std::unique_ptr<Tool> solink = Tool::CreateTool(CTool::kCToolSolink);
523   CTool* solink_tool = solink->AsC();
524   solink_tool->set_output_prefix("lib");
525   solink_tool->set_default_output_extension(".so");
526 
527   const char kLinkPattern[] =
528       "{{root_out_dir}}/{{target_output_name}}{{output_extension}}";
529   SubstitutionPattern link_output =
530       SubstitutionPattern::MakeForTest(kLinkPattern);
531   solink_tool->set_link_output(link_output);
532 
533   const char kDependPattern[] =
534       "{{root_out_dir}}/{{target_output_name}}{{output_extension}}.TOC";
535   SubstitutionPattern depend_output =
536       SubstitutionPattern::MakeForTest(kDependPattern);
537   solink_tool->set_depend_output(depend_output);
538 
539   solink_tool->set_outputs(
540       SubstitutionList::MakeForTest(kLinkPattern, kDependPattern));
541 
542   toolchain.SetTool(std::move(solink));
543 
544   Target target(setup.settings(), Label(SourceDir("//a/"), "a"));
545   target.set_output_type(Target::SHARED_LIBRARY);
546   target.SetToolchain(&toolchain);
547   ASSERT_TRUE(target.OnResolved(&err));
548 
549   EXPECT_EQ("./liba.so", target.link_output_file().value());
550   EXPECT_EQ("./liba.so.TOC", target.dependency_output_file().value());
551 
552   ASSERT_EQ(1u, target.runtime_outputs().size());
553   EXPECT_EQ("./liba.so", target.runtime_outputs()[0].value());
554 }
555 
556 // Tests that runtime_outputs works without an explicit link_output for
557 // solink tools.
558 //
559 // Also tests GetOutputsAsSourceFiles() for binaries (the setup is the same).
TEST_F(TargetTest,RuntimeOuputs)560 TEST_F(TargetTest, RuntimeOuputs) {
561   TestWithScope setup;
562   Err err;
563 
564   Toolchain toolchain(setup.settings(), Label(SourceDir("//tc/"), "tc"));
565 
566   std::unique_ptr<Tool> solink = Tool::CreateTool(CTool::kCToolSolink);
567   CTool* solink_tool = solink->AsC();
568   solink_tool->set_output_prefix("");
569   solink_tool->set_default_output_extension(".dll");
570 
571   // Say the linker makes a DLL< an import library, and a symbol file we want
572   // to treat as a runtime output.
573   const char kLibPattern[] =
574       "{{root_out_dir}}/{{target_output_name}}{{output_extension}}.lib";
575   const char kDllPattern[] =
576       "{{root_out_dir}}/{{target_output_name}}{{output_extension}}";
577   const char kPdbPattern[] = "{{root_out_dir}}/{{target_output_name}}.pdb";
578   SubstitutionPattern pdb_pattern =
579       SubstitutionPattern::MakeForTest(kPdbPattern);
580 
581   solink_tool->set_outputs(
582       SubstitutionList::MakeForTest(kLibPattern, kDllPattern, kPdbPattern));
583 
584   // Say we only want the DLL and symbol file treaded as runtime outputs.
585   solink_tool->set_runtime_outputs(
586       SubstitutionList::MakeForTest(kDllPattern, kPdbPattern));
587 
588   toolchain.SetTool(std::move(solink));
589 
590   Target target(setup.settings(), Label(SourceDir("//a/"), "a"));
591   target.set_output_type(Target::SHARED_LIBRARY);
592   target.SetToolchain(&toolchain);
593   ASSERT_TRUE(target.OnResolved(&err));
594 
595   EXPECT_EQ("./a.dll.lib", target.link_output_file().value());
596   EXPECT_EQ("./a.dll.lib", target.dependency_output_file().value());
597 
598   ASSERT_EQ(2u, target.runtime_outputs().size());
599   EXPECT_EQ("./a.dll", target.runtime_outputs()[0].value());
600   EXPECT_EQ("./a.pdb", target.runtime_outputs()[1].value());
601 
602   // Test GetOutputsAsSourceFiles().
603   std::vector<SourceFile> computed_outputs;
604   EXPECT_TRUE(target.GetOutputsAsSourceFiles(LocationRange(), true,
605                                              &computed_outputs, &err));
606   ASSERT_EQ(3u, computed_outputs.size());
607   EXPECT_EQ("//out/Debug/a.dll.lib", computed_outputs[0].value());
608   EXPECT_EQ("//out/Debug/a.dll", computed_outputs[1].value());
609   EXPECT_EQ("//out/Debug/a.pdb", computed_outputs[2].value());
610 }
611 
612 // Tests Target::GetOutputFilesForSource for binary targets (these require a
613 // tool definition). Also tests GetOutputsAsSourceFiles() for source sets.
TEST_F(TargetTest,GetOutputFilesForSource_Binary)614 TEST_F(TargetTest, GetOutputFilesForSource_Binary) {
615   TestWithScope setup;
616 
617   Toolchain toolchain(setup.settings(), Label(SourceDir("//tc/"), "tc"));
618 
619   std::unique_ptr<Tool> tool = Tool::CreateTool(CTool::kCToolCxx);
620   CTool* cxx = tool->AsC();
621   cxx->set_outputs(SubstitutionList::MakeForTest("{{source_file_part}}.o"));
622   toolchain.SetTool(std::move(tool));
623 
624   Target target(setup.settings(), Label(SourceDir("//a/"), "a"));
625   target.set_output_type(Target::SOURCE_SET);
626   target.SetToolchain(&toolchain);
627   Err err;
628   ASSERT_TRUE(target.OnResolved(&err));
629 
630   const char* computed_tool_type = nullptr;
631   std::vector<OutputFile> output;
632   bool result = target.GetOutputFilesForSource(SourceFile("//source/input.cc"),
633                                                &computed_tool_type, &output);
634   ASSERT_TRUE(result);
635   EXPECT_EQ(std::string("cxx"), std::string(computed_tool_type));
636 
637   // Outputs are relative to the build directory "//out/Debug/".
638   ASSERT_EQ(1u, output.size());
639   EXPECT_EQ("input.cc.o", output[0].value()) << output[0].value();
640 
641   // Test GetOutputsAsSourceFiles(). Since this is a source set it should give a
642   // stamp file.
643   std::vector<SourceFile> computed_outputs;
644   EXPECT_TRUE(target.GetOutputsAsSourceFiles(LocationRange(), true,
645                                              &computed_outputs, &err));
646   ASSERT_EQ(1u, computed_outputs.size());
647   EXPECT_EQ("//out/Debug/obj/a/a.stamp", computed_outputs[0].value());
648 }
649 
TEST_F(TargetTest,CheckStampFileName)650 TEST_F(TargetTest, CheckStampFileName) {
651   TestWithScope setup;
652 
653   Toolchain toolchain(setup.settings(), Label(SourceDir("//tc/"), "tc"));
654 
655   std::unique_ptr<Tool> tool = Tool::CreateTool(CTool::kCToolCxx);
656   CTool* cxx = tool->AsC();
657   cxx->set_outputs(SubstitutionList::MakeForTest("{{source_file_part}}.o"));
658   toolchain.SetTool(std::move(tool));
659 
660   Target target(setup.settings(), Label(SourceDir("//a/"), "a"));
661   target.set_output_type(Target::SOURCE_SET);
662   target.SetToolchain(&toolchain);
663 
664   // Change the output artifact name on purpose.
665   target.set_output_name("b");
666 
667   Err err;
668   ASSERT_TRUE(target.OnResolved(&err));
669 
670   // Test GetOutputsAsSourceFiles(). Since this is a source set it should give a
671   // stamp file.
672   std::vector<SourceFile> computed_outputs;
673   EXPECT_TRUE(target.GetOutputsAsSourceFiles(LocationRange(), true,
674                                              &computed_outputs, &err));
675   ASSERT_EQ(1u, computed_outputs.size());
676   EXPECT_EQ("//out/Debug/obj/a/a.stamp", computed_outputs[0].value())
677       << "was instead: " << computed_outputs[0].value();
678 }
679 
680 // Tests Target::GetOutputFilesForSource for action_foreach targets (these, like
681 // copy targets, apply a pattern to the source file). Also tests
682 // GetOutputsAsSourceFiles() for action_foreach().
TEST_F(TargetTest,GetOutputFilesForSource_ActionForEach)683 TEST_F(TargetTest, GetOutputFilesForSource_ActionForEach) {
684   TestWithScope setup;
685 
686   TestTarget target(setup, "//a:a", Target::ACTION_FOREACH);
687   target.sources().push_back(SourceFile("//a/source_file1.txt"));
688   target.sources().push_back(SourceFile("//a/source_file2.txt"));
689   target.action_values().outputs() =
690       SubstitutionList::MakeForTest("//out/Debug/{{source_file_part}}.one",
691                                     "//out/Debug/{{source_file_part}}.two");
692   Err err;
693   ASSERT_TRUE(target.OnResolved(&err));
694 
695   const char* computed_tool_type = nullptr;
696   std::vector<OutputFile> output;
697   bool result = target.GetOutputFilesForSource(SourceFile("//source/input.txt"),
698                                                &computed_tool_type, &output);
699   ASSERT_TRUE(result);
700 
701   // Outputs are relative to the build directory "//out/Debug/".
702   ASSERT_EQ(2u, output.size());
703   EXPECT_EQ("input.txt.one", output[0].value());
704   EXPECT_EQ("input.txt.two", output[1].value());
705 
706   // Test GetOutputsAsSourceFiles(). It should give both outputs for each of the
707   // two inputs.
708   std::vector<SourceFile> computed_outputs;
709   EXPECT_TRUE(target.GetOutputsAsSourceFiles(LocationRange(), true,
710                                              &computed_outputs, &err));
711   ASSERT_EQ(4u, computed_outputs.size());
712   EXPECT_EQ("//out/Debug/source_file1.txt.one", computed_outputs[0].value());
713   EXPECT_EQ("//out/Debug/source_file1.txt.two", computed_outputs[1].value());
714   EXPECT_EQ("//out/Debug/source_file2.txt.one", computed_outputs[2].value());
715   EXPECT_EQ("//out/Debug/source_file2.txt.two", computed_outputs[3].value());
716 }
717 
718 // Tests Target::GetOutputFilesForSource for action targets (these just list the
719 // output of the action as the result of all possible inputs). This should also
720 // cover everything other than binary, action_foreach, and copy targets.
TEST_F(TargetTest,GetOutputFilesForSource_Action)721 TEST_F(TargetTest, GetOutputFilesForSource_Action) {
722   TestWithScope setup;
723 
724   TestTarget target(setup, "//a:a", Target::ACTION);
725   target.sources().push_back(SourceFile("//a/source_file1.txt"));
726   target.action_values().outputs() =
727       SubstitutionList::MakeForTest("//out/Debug/one", "//out/Debug/two");
728   Err err;
729   ASSERT_TRUE(target.OnResolved(&err));
730 
731   const char* computed_tool_type = nullptr;
732   std::vector<OutputFile> output;
733   bool result = target.GetOutputFilesForSource(SourceFile("//source/input.txt"),
734                                                &computed_tool_type, &output);
735   ASSERT_TRUE(result);
736 
737   // Outputs are relative to the build directory "//out/Debug/".
738   ASSERT_EQ(2u, output.size());
739   EXPECT_EQ("one", output[0].value());
740   EXPECT_EQ("two", output[1].value());
741 
742   // Test GetOutputsAsSourceFiles(). It should give the listed outputs.
743   std::vector<SourceFile> computed_outputs;
744   EXPECT_TRUE(target.GetOutputsAsSourceFiles(LocationRange(), true,
745                                              &computed_outputs, &err));
746   ASSERT_EQ(2u, computed_outputs.size());
747   EXPECT_EQ("//out/Debug/one", computed_outputs[0].value());
748   EXPECT_EQ("//out/Debug/two", computed_outputs[1].value());
749 
750   // Test that the copy target type behaves the same. This target requires only
751   // one output.
752   target.action_values().outputs() =
753       SubstitutionList::MakeForTest("//out/Debug/one");
754   target.set_output_type(Target::COPY_FILES);
755 
756   // Outputs are relative to the build directory "//out/Debug/".
757   result = target.GetOutputFilesForSource(SourceFile("//source/input.txt"),
758                                           &computed_tool_type, &output);
759   ASSERT_TRUE(result);
760   ASSERT_EQ(1u, output.size());
761   EXPECT_EQ("one", output[0].value());
762 
763   // Test GetOutputsAsSourceFiles() for the copy case.
764   EXPECT_TRUE(target.GetOutputsAsSourceFiles(LocationRange(), true,
765                                              &computed_outputs, &err));
766   ASSERT_EQ(1u, computed_outputs.size()) << computed_outputs.size();
767   EXPECT_EQ("//out/Debug/one", computed_outputs[0].value());
768 }
769 
TEST_F(TargetTest,GeneratedInputs)770 TEST_F(TargetTest, GeneratedInputs) {
771   TestWithScope setup;
772   Err err;
773 
774   SourceFile generated_file("//out/Debug/generated.cc");
775 
776   // This target has a generated input and no dependency makes it.
777   TestTarget non_existent_generator(setup, "//foo:non_existent_generator",
778                                     Target::EXECUTABLE);
779   non_existent_generator.sources().push_back(generated_file);
780   EXPECT_TRUE(non_existent_generator.OnResolved(&err)) << err.message();
781   AssertSchedulerHasOneUnknownFileMatching(&non_existent_generator,
782                                            generated_file);
783   scheduler().ClearUnknownGeneratedInputsAndWrittenFiles();
784 
785   // Make a target that generates the file.
786   TestTarget generator(setup, "//foo:generator", Target::ACTION);
787   generator.action_values().outputs() =
788       SubstitutionList::MakeForTest(generated_file.value().c_str());
789   err = Err();
790   EXPECT_TRUE(generator.OnResolved(&err)) << err.message();
791 
792   // A target that depends on the generator that uses the file as a source
793   // should be OK. This uses a private dep (will be used later).
794   TestTarget existent_generator(setup, "//foo:existent_generator",
795                                 Target::SHARED_LIBRARY);
796   existent_generator.sources().push_back(generated_file);
797   existent_generator.private_deps().push_back(LabelTargetPair(&generator));
798   EXPECT_TRUE(existent_generator.OnResolved(&err)) << err.message();
799   EXPECT_TRUE(scheduler().GetUnknownGeneratedInputs().empty());
800 
801   // A target that depends on the previous one should *not* be allowed to
802   // use the generated file, because existent_generator used private deps.
803   // This is:
804   //    indirect_private --> existent_generator --[private]--> generator
805   TestTarget indirect_private(setup, "//foo:indirect_private",
806                               Target::EXECUTABLE);
807   indirect_private.sources().push_back(generated_file);
808   indirect_private.public_deps().push_back(
809       LabelTargetPair(&existent_generator));
810   EXPECT_TRUE(indirect_private.OnResolved(&err));
811   AssertSchedulerHasOneUnknownFileMatching(&indirect_private, generated_file);
812   scheduler().ClearUnknownGeneratedInputsAndWrittenFiles();
813 
814   // Now make a chain like the above but with all public deps, it should be OK.
815   TestTarget existent_public(setup, "//foo:existent_public",
816                              Target::SHARED_LIBRARY);
817   existent_public.public_deps().push_back(LabelTargetPair(&generator));
818   EXPECT_TRUE(existent_public.OnResolved(&err)) << err.message();
819   TestTarget indirect_public(setup, "//foo:indirect_public",
820                              Target::EXECUTABLE);
821   indirect_public.sources().push_back(generated_file);
822   indirect_public.public_deps().push_back(LabelTargetPair(&existent_public));
823   EXPECT_TRUE(indirect_public.OnResolved(&err)) << err.message();
824   EXPECT_TRUE(scheduler().GetUnknownGeneratedInputs().empty());
825 }
826 
827 // This is sort of a Scheduler test, but is related to the above test more.
TEST_F(TargetTest,WriteFileGeneratedInputs)828 TEST_F(TargetTest, WriteFileGeneratedInputs) {
829   TestWithScope setup;
830   Err err;
831 
832   SourceFile generated_file("//out/Debug/generated.data");
833 
834   // This target has a generated input and no dependency makes it.
835   TestTarget non_existent_generator(setup, "//foo:non_existent_generator",
836                                     Target::EXECUTABLE);
837   non_existent_generator.sources().push_back(generated_file);
838   EXPECT_TRUE(non_existent_generator.OnResolved(&err));
839   AssertSchedulerHasOneUnknownFileMatching(&non_existent_generator,
840                                            generated_file);
841   scheduler().ClearUnknownGeneratedInputsAndWrittenFiles();
842 
843   // This target has a generated file and we've decared we write it.
844   TestTarget existent_generator(setup, "//foo:existent_generator",
845                                 Target::EXECUTABLE);
846   existent_generator.sources().push_back(generated_file);
847   EXPECT_TRUE(existent_generator.OnResolved(&err));
848   scheduler().AddWrittenFile(generated_file);
849 
850   // Should be OK.
851   EXPECT_TRUE(scheduler().GetUnknownGeneratedInputs().empty());
852 }
853 
TEST_F(TargetTest,WriteRuntimeDepsGeneratedInputs)854 TEST_F(TargetTest, WriteRuntimeDepsGeneratedInputs) {
855   TestWithScope setup;
856   Err err;
857 
858   SourceFile source_file("//out/Debug/generated.runtime_deps");
859   OutputFile output_file(setup.build_settings(), source_file);
860 
861   TestTarget generator(setup, "//foo:generator", Target::EXECUTABLE);
862   generator.set_write_runtime_deps_output(output_file);
863   g_scheduler->AddWriteRuntimeDepsTarget(&generator);
864 
865   TestTarget middle_data_dep(setup, "//foo:middle", Target::EXECUTABLE);
866   middle_data_dep.data_deps().push_back(LabelTargetPair(&generator));
867 
868   // This target has a generated input and no dependency makes it.
869   TestTarget dep_missing(setup, "//foo:no_dep", Target::EXECUTABLE);
870   dep_missing.sources().push_back(source_file);
871   EXPECT_TRUE(dep_missing.OnResolved(&err));
872   AssertSchedulerHasOneUnknownFileMatching(&dep_missing, source_file);
873   scheduler().ClearUnknownGeneratedInputsAndWrittenFiles();
874 
875   // This target has a generated file and we've directly dependended on it.
876   TestTarget dep_present(setup, "//foo:with_dep", Target::EXECUTABLE);
877   dep_present.sources().push_back(source_file);
878   dep_present.private_deps().push_back(LabelTargetPair(&generator));
879   EXPECT_TRUE(dep_present.OnResolved(&err));
880   EXPECT_TRUE(scheduler().GetUnknownGeneratedInputs().empty());
881 
882   // This target has a generated file and we've indirectly dependended on it
883   // via data_deps.
884   TestTarget dep_indirect(setup, "//foo:with_dep", Target::EXECUTABLE);
885   dep_indirect.sources().push_back(source_file);
886   dep_indirect.data_deps().push_back(LabelTargetPair(&middle_data_dep));
887   EXPECT_TRUE(dep_indirect.OnResolved(&err));
888   AssertSchedulerHasOneUnknownFileMatching(&dep_indirect, source_file);
889   scheduler().ClearUnknownGeneratedInputsAndWrittenFiles();
890 
891   // This target has a generated file and we've directly dependended on it
892   // via data_deps.
893   TestTarget data_dep_present(setup, "//foo:with_dep", Target::EXECUTABLE);
894   data_dep_present.sources().push_back(source_file);
895   data_dep_present.data_deps().push_back(LabelTargetPair(&generator));
896   EXPECT_TRUE(data_dep_present.OnResolved(&err));
897   EXPECT_TRUE(scheduler().GetUnknownGeneratedInputs().empty());
898 }
899 
900 // Tests that intermediate object files generated by binary targets are also
901 // considered generated for the purposes of input checking. Above, we tested
902 // the failure cases for generated inputs, so here only test .o files that are
903 // present.
TEST_F(TargetTest,ObjectGeneratedInputs)904 TEST_F(TargetTest, ObjectGeneratedInputs) {
905   TestWithScope setup;
906   Err err;
907 
908   // This target compiles the source.
909   SourceFile source_file("//source.cc");
910   TestTarget source_generator(setup, "//:source_target", Target::SOURCE_SET);
911   source_generator.sources().push_back(source_file);
912   EXPECT_TRUE(source_generator.OnResolved(&err));
913 
914   // This is the object file that the test toolchain generates for the source.
915   SourceFile object_file("//out/Debug/obj/source_target.source.o");
916 
917   TestTarget final_target(setup, "//:final", Target::ACTION);
918   final_target.config_values().inputs().push_back(object_file);
919   EXPECT_TRUE(final_target.OnResolved(&err));
920 
921   AssertSchedulerHasOneUnknownFileMatching(&final_target, object_file);
922 }
923 
TEST_F(TargetTest,ResolvePrecompiledHeaders)924 TEST_F(TargetTest, ResolvePrecompiledHeaders) {
925   TestWithScope setup;
926   Err err;
927 
928   Target target(setup.settings(), Label(SourceDir("//foo/"), "bar",
929                                         SourceDir("//toolchain/"), "default"));
930 
931   // Target with no settings, no configs, should be a no-op.
932   EXPECT_TRUE(target.ResolvePrecompiledHeaders(&err));
933 
934   // Config with PCH values.
935   Config config_1(
936       setup.settings(),
937       Label(SourceDir("//foo/"), "c1", SourceDir("//toolchain/"), "default"));
938   std::string pch_1("pch.h");
939   SourceFile pcs_1("//pcs.cc");
940   config_1.own_values().set_precompiled_header(pch_1);
941   config_1.own_values().set_precompiled_source(pcs_1);
942   ASSERT_TRUE(config_1.OnResolved(&err));
943   target.configs().push_back(LabelConfigPair(&config_1));
944 
945   // No PCH info specified on TargetTest, but the config specifies one, the
946   // values should get copied to the target.
947   EXPECT_TRUE(target.ResolvePrecompiledHeaders(&err));
948   EXPECT_EQ(pch_1, target.config_values().precompiled_header());
949   EXPECT_TRUE(target.config_values().precompiled_source() == pcs_1);
950 
951   // Now both target and config have matching PCH values. Resolving again
952   // should be a no-op since they all match.
953   EXPECT_TRUE(target.ResolvePrecompiledHeaders(&err));
954   EXPECT_TRUE(target.config_values().precompiled_header() == pch_1);
955   EXPECT_TRUE(target.config_values().precompiled_source() == pcs_1);
956 
957   // Second config with different PCH values.
958   Config config_2(
959       setup.settings(),
960       Label(SourceDir("//foo/"), "c2", SourceDir("//toolchain/"), "default"));
961   std::string pch_2("pch2.h");
962   SourceFile pcs_2("//pcs2.cc");
963   config_2.own_values().set_precompiled_header(pch_2);
964   config_2.own_values().set_precompiled_source(pcs_2);
965   ASSERT_TRUE(config_2.OnResolved(&err));
966   target.configs().push_back(LabelConfigPair(&config_2));
967 
968   // This should be an error since they don't match.
969   EXPECT_FALSE(target.ResolvePrecompiledHeaders(&err));
970 
971   // Make sure the proper labels are blamed.
972   EXPECT_EQ(
973       "The target //foo:bar\n"
974       "has conflicting precompiled header settings.\n"
975       "\n"
976       "From //foo:bar\n"
977       "  header: pch.h\n"
978       "  source: //pcs.cc\n"
979       "\n"
980       "From //foo:c2\n"
981       "  header: pch2.h\n"
982       "  source: //pcs2.cc",
983       err.help_text());
984 }
985 
TEST_F(TargetTest,AssertNoDeps)986 TEST_F(TargetTest, AssertNoDeps) {
987   TestWithScope setup;
988   Err err;
989 
990   // A target.
991   TestTarget a(setup, "//a", Target::SHARED_LIBRARY);
992   ASSERT_TRUE(a.OnResolved(&err));
993 
994   // B depends on A and has an assert_no_deps for a random dir.
995   TestTarget b(setup, "//b", Target::SHARED_LIBRARY);
996   b.private_deps().push_back(LabelTargetPair(&a));
997   b.assert_no_deps().push_back(LabelPattern(LabelPattern::RECURSIVE_DIRECTORY,
998                                             SourceDir("//disallowed/"),
999                                             std::string(), Label()));
1000   ASSERT_TRUE(b.OnResolved(&err));
1001 
1002   LabelPattern disallow_a(LabelPattern::RECURSIVE_DIRECTORY, SourceDir("//a/"),
1003                           std::string(), Label());
1004 
1005   // C depends on B and disallows depending on A. This should fail.
1006   TestTarget c(setup, "//c", Target::EXECUTABLE);
1007   c.private_deps().push_back(LabelTargetPair(&b));
1008   c.assert_no_deps().push_back(disallow_a);
1009   ASSERT_FALSE(c.OnResolved(&err));
1010 
1011   // Validate the error message has the proper path.
1012   EXPECT_EQ(
1013       "//c:c has an assert_no_deps entry:\n"
1014       "  //a/*\n"
1015       "which fails for the dependency path:\n"
1016       "  //c:c ->\n"
1017       "  //b:b ->\n"
1018       "  //a:a",
1019       err.help_text());
1020   err = Err();
1021 
1022   // Add an intermediate executable with: exe -> b -> a
1023   TestTarget exe(setup, "//exe", Target::EXECUTABLE);
1024   exe.private_deps().push_back(LabelTargetPair(&b));
1025   ASSERT_TRUE(exe.OnResolved(&err));
1026 
1027   // D depends on the executable and disallows depending on A. Since there is
1028   // an intermediate executable, this should be OK.
1029   TestTarget d(setup, "//d", Target::EXECUTABLE);
1030   d.private_deps().push_back(LabelTargetPair(&exe));
1031   d.assert_no_deps().push_back(disallow_a);
1032   ASSERT_TRUE(d.OnResolved(&err));
1033 
1034   // A2 disallows depending on anything in its own directory, but the
1035   // assertions should not match the target itself so this should be OK.
1036   TestTarget a2(setup, "//a:a2", Target::EXECUTABLE);
1037   a2.assert_no_deps().push_back(disallow_a);
1038   ASSERT_TRUE(a2.OnResolved(&err));
1039 }
1040 
TEST_F(TargetTest,PullRecursiveBundleData)1041 TEST_F(TargetTest, PullRecursiveBundleData) {
1042   TestWithScope setup;
1043   Err err;
1044 
1045   // We have the following dependency graph:
1046   // A (create_bundle) -> B (bundle_data)
1047   //                  \-> C (create_bundle) -> D (bundle_data)
1048   //                  \-> E (group) -> F (bundle_data)
1049   //                               \-> B (bundle_data)
1050   TestTarget a(setup, "//foo:a", Target::CREATE_BUNDLE);
1051   TestTarget b(setup, "//foo:b", Target::BUNDLE_DATA);
1052   TestTarget c(setup, "//foo:c", Target::CREATE_BUNDLE);
1053   TestTarget d(setup, "//foo:d", Target::BUNDLE_DATA);
1054   TestTarget e(setup, "//foo:e", Target::GROUP);
1055   TestTarget f(setup, "//foo:f", Target::BUNDLE_DATA);
1056   a.public_deps().push_back(LabelTargetPair(&b));
1057   a.public_deps().push_back(LabelTargetPair(&c));
1058   a.public_deps().push_back(LabelTargetPair(&e));
1059   c.public_deps().push_back(LabelTargetPair(&d));
1060   e.public_deps().push_back(LabelTargetPair(&f));
1061   e.public_deps().push_back(LabelTargetPair(&b));
1062 
1063   a.bundle_data().root_dir() = SourceDir("//out/foo_a.bundle");
1064   a.bundle_data().resources_dir() = SourceDir("//out/foo_a.bundle/Resources");
1065 
1066   b.sources().push_back(SourceFile("//foo/b1.txt"));
1067   b.sources().push_back(SourceFile("//foo/b2.txt"));
1068   b.action_values().outputs() = SubstitutionList::MakeForTest(
1069       "{{bundle_resources_dir}}/{{source_file_part}}");
1070   ASSERT_TRUE(b.OnResolved(&err));
1071 
1072   c.bundle_data().root_dir() = SourceDir("//out/foo_c.bundle");
1073   c.bundle_data().resources_dir() = SourceDir("//out/foo_c.bundle/Resources");
1074 
1075   d.sources().push_back(SourceFile("//foo/d.txt"));
1076   d.action_values().outputs() = SubstitutionList::MakeForTest(
1077       "{{bundle_resources_dir}}/{{source_file_part}}");
1078   ASSERT_TRUE(d.OnResolved(&err));
1079 
1080   f.sources().push_back(SourceFile("//foo/f1.txt"));
1081   f.sources().push_back(SourceFile("//foo/f2.txt"));
1082   f.sources().push_back(SourceFile("//foo/f3.txt"));
1083   f.sources().push_back(
1084       SourceFile("//foo/Foo.xcassets/foo.imageset/Contents.json"));
1085   f.sources().push_back(
1086       SourceFile("//foo/Foo.xcassets/foo.imageset/FooEmpty-29.png"));
1087   f.sources().push_back(
1088       SourceFile("//foo/Foo.xcassets/foo.imageset/FooEmpty-29@2x.png"));
1089   f.sources().push_back(
1090       SourceFile("//foo/Foo.xcassets/foo.imageset/FooEmpty-29@3x.png"));
1091   f.sources().push_back(
1092       SourceFile("//foo/Foo.xcassets/file/with/no/known/pattern"));
1093   f.sources().push_back(
1094       SourceFile("//foo/Foo.xcassets/nested/bar.xcassets/my/file"));
1095   f.action_values().outputs() = SubstitutionList::MakeForTest(
1096       "{{bundle_resources_dir}}/{{source_file_part}}");
1097   ASSERT_TRUE(f.OnResolved(&err));
1098 
1099   ASSERT_TRUE(e.OnResolved(&err));
1100   ASSERT_TRUE(c.OnResolved(&err));
1101   ASSERT_TRUE(a.OnResolved(&err));
1102 
1103   // A gets its data from B and F.
1104   ASSERT_EQ(a.bundle_data().file_rules().size(), 2u);
1105   ASSERT_EQ(a.bundle_data().file_rules()[0].sources().size(), 2u);
1106   ASSERT_EQ(a.bundle_data().file_rules()[1].sources().size(), 3u);
1107   ASSERT_EQ(a.bundle_data().assets_catalog_sources().size(), 1u);
1108   ASSERT_EQ(a.bundle_data().forwarded_bundle_deps().size(), 2u);
1109 
1110   // C gets its data from D.
1111   ASSERT_EQ(c.bundle_data().file_rules().size(), 1u);
1112   ASSERT_EQ(c.bundle_data().file_rules()[0].sources().size(), 1u);
1113   ASSERT_EQ(c.bundle_data().forwarded_bundle_deps().size(), 1u);
1114 
1115   // E does not have any bundle_data information but gets a list of
1116   // forwarded_bundle_deps to propagate them during target resolution.
1117   ASSERT_TRUE(e.bundle_data().file_rules().empty());
1118   ASSERT_TRUE(e.bundle_data().assets_catalog_sources().empty());
1119   ASSERT_EQ(e.bundle_data().forwarded_bundle_deps().size(), 2u);
1120 }
1121 
TEST(TargetTest,CollectMetadataNoRecurse)1122 TEST(TargetTest, CollectMetadataNoRecurse) {
1123   TestWithScope setup;
1124 
1125   TestTarget one(setup, "//foo:one", Target::SOURCE_SET);
1126   Value a_expected(nullptr, Value::LIST);
1127   a_expected.list_value().push_back(Value(nullptr, "foo"));
1128   one.metadata().contents().insert(
1129       std::pair<std::string_view, Value>("a", a_expected));
1130 
1131   Value b_expected(nullptr, Value::LIST);
1132   b_expected.list_value().push_back(Value(nullptr, true));
1133   one.metadata().contents().insert(
1134       std::pair<std::string_view, Value>("b", b_expected));
1135 
1136   one.metadata().set_source_dir(SourceDir("/usr/home/files/"));
1137 
1138   std::vector<std::string> data_keys;
1139   data_keys.push_back("a");
1140   data_keys.push_back("b");
1141 
1142   std::vector<std::string> walk_keys;
1143 
1144   Err err;
1145   std::vector<Value> result;
1146   TargetSet targets;
1147   one.GetMetadata(data_keys, walk_keys, SourceDir(), false, &result, &targets,
1148                   &err);
1149   EXPECT_FALSE(err.has_error());
1150 
1151   std::vector<Value> expected;
1152   expected.push_back(Value(nullptr, "foo"));
1153   expected.push_back(Value(nullptr, true));
1154   EXPECT_EQ(result, expected);
1155 }
1156 
TEST(TargetTest,CollectMetadataWithRecurse)1157 TEST(TargetTest, CollectMetadataWithRecurse) {
1158   TestWithScope setup;
1159 
1160   TestTarget one(setup, "//foo:one", Target::SOURCE_SET);
1161   Value a_expected(nullptr, Value::LIST);
1162   a_expected.list_value().push_back(Value(nullptr, "foo"));
1163   one.metadata().contents().insert(
1164       std::pair<std::string_view, Value>("a", a_expected));
1165 
1166   Value b_expected(nullptr, Value::LIST);
1167   b_expected.list_value().push_back(Value(nullptr, true));
1168   one.metadata().contents().insert(
1169       std::pair<std::string_view, Value>("b", b_expected));
1170 
1171   TestTarget two(setup, "//foo:two", Target::SOURCE_SET);
1172   Value a_2_expected(nullptr, Value::LIST);
1173   a_2_expected.list_value().push_back(Value(nullptr, "bar"));
1174   two.metadata().contents().insert(
1175       std::pair<std::string_view, Value>("a", a_2_expected));
1176 
1177   one.public_deps().push_back(LabelTargetPair(&two));
1178 
1179   std::vector<std::string> data_keys;
1180   data_keys.push_back("a");
1181   data_keys.push_back("b");
1182 
1183   std::vector<std::string> walk_keys;
1184 
1185   Err err;
1186   std::vector<Value> result;
1187   TargetSet targets;
1188   one.GetMetadata(data_keys, walk_keys, SourceDir(), false, &result, &targets,
1189                   &err);
1190   EXPECT_FALSE(err.has_error());
1191 
1192   std::vector<Value> expected;
1193   expected.push_back(Value(nullptr, "bar"));
1194   expected.push_back(Value(nullptr, "foo"));
1195   expected.push_back(Value(nullptr, true));
1196   EXPECT_EQ(result, expected);
1197 }
1198 
TEST(TargetTest,CollectMetadataWithRecurseHole)1199 TEST(TargetTest, CollectMetadataWithRecurseHole) {
1200   TestWithScope setup;
1201 
1202   TestTarget one(setup, "//foo:one", Target::SOURCE_SET);
1203   Value a_expected(nullptr, Value::LIST);
1204   a_expected.list_value().push_back(Value(nullptr, "foo"));
1205   one.metadata().contents().insert(
1206       std::pair<std::string_view, Value>("a", a_expected));
1207 
1208   Value b_expected(nullptr, Value::LIST);
1209   b_expected.list_value().push_back(Value(nullptr, true));
1210   one.metadata().contents().insert(
1211       std::pair<std::string_view, Value>("b", b_expected));
1212 
1213   // Target two does not have metadata but depends on three
1214   // which does.
1215   TestTarget two(setup, "//foo:two", Target::SOURCE_SET);
1216 
1217   TestTarget three(setup, "//foo:three", Target::SOURCE_SET);
1218   Value a_3_expected(nullptr, Value::LIST);
1219   a_3_expected.list_value().push_back(Value(nullptr, "bar"));
1220   three.metadata().contents().insert(
1221       std::pair<std::string_view, Value>("a", a_3_expected));
1222 
1223   one.public_deps().push_back(LabelTargetPair(&two));
1224   two.public_deps().push_back(LabelTargetPair(&three));
1225 
1226   std::vector<std::string> data_keys;
1227   data_keys.push_back("a");
1228   data_keys.push_back("b");
1229 
1230   std::vector<std::string> walk_keys;
1231 
1232   Err err;
1233   std::vector<Value> result;
1234   TargetSet targets;
1235   one.GetMetadata(data_keys, walk_keys, SourceDir(), false, &result, &targets,
1236                   &err);
1237   EXPECT_FALSE(err.has_error());
1238 
1239   std::vector<Value> expected;
1240   expected.push_back(Value(nullptr, "bar"));
1241   expected.push_back(Value(nullptr, "foo"));
1242   expected.push_back(Value(nullptr, true));
1243   EXPECT_EQ(result, expected);
1244 }
1245 
TEST(TargetTest,CollectMetadataWithBarrier)1246 TEST(TargetTest, CollectMetadataWithBarrier) {
1247   TestWithScope setup;
1248 
1249   TestTarget one(setup, "//foo:one", Target::SOURCE_SET);
1250   Value a_expected(nullptr, Value::LIST);
1251   a_expected.list_value().push_back(Value(nullptr, "foo"));
1252   one.metadata().contents().insert(
1253       std::pair<std::string_view, Value>("a", a_expected));
1254 
1255   Value walk_expected(nullptr, Value::LIST);
1256   walk_expected.list_value().push_back(Value(nullptr, "two"));
1257   one.metadata().contents().insert(
1258       std::pair<std::string_view, Value>("walk", walk_expected));
1259 
1260   TestTarget two(setup, "//foo/two:two", Target::SOURCE_SET);
1261   Value a_2_expected(nullptr, Value::LIST);
1262   a_2_expected.list_value().push_back(Value(nullptr, "bar"));
1263   two.metadata().contents().insert(
1264       std::pair<std::string_view, Value>("a", a_2_expected));
1265 
1266   TestTarget three(setup, "//foo:three", Target::SOURCE_SET);
1267   Value a_3_expected(nullptr, Value::LIST);
1268   a_3_expected.list_value().push_back(Value(nullptr, "baz"));
1269   three.metadata().contents().insert(
1270       std::pair<std::string_view, Value>("a", a_3_expected));
1271 
1272   one.private_deps().push_back(LabelTargetPair(&two));
1273   one.public_deps().push_back(LabelTargetPair(&three));
1274 
1275   std::vector<std::string> data_keys;
1276   data_keys.push_back("a");
1277 
1278   std::vector<std::string> walk_keys;
1279   walk_keys.push_back("walk");
1280 
1281   Err err;
1282   std::vector<Value> result;
1283   TargetSet targets;
1284   one.GetMetadata(data_keys, walk_keys, SourceDir(), false, &result, &targets,
1285                   &err);
1286   EXPECT_FALSE(err.has_error()) << err.message();
1287 
1288   std::vector<Value> expected;
1289   expected.push_back(Value(nullptr, "bar"));
1290   expected.push_back(Value(nullptr, "foo"));
1291   EXPECT_EQ(result, expected) << result.size();
1292 }
1293 
TEST(TargetTest,CollectMetadataWithError)1294 TEST(TargetTest, CollectMetadataWithError) {
1295   TestWithScope setup;
1296 
1297   TestTarget one(setup, "//foo:one", Target::SOURCE_SET);
1298   Value a_expected(nullptr, Value::LIST);
1299   a_expected.list_value().push_back(Value(nullptr, "foo"));
1300   one.metadata().contents().insert(
1301       std::pair<std::string_view, Value>("a", a_expected));
1302 
1303   Value walk_expected(nullptr, Value::LIST);
1304   walk_expected.list_value().push_back(Value(nullptr, "//foo:missing"));
1305   one.metadata().contents().insert(
1306       std::pair<std::string_view, Value>("walk", walk_expected));
1307 
1308   std::vector<std::string> data_keys;
1309   data_keys.push_back("a");
1310 
1311   std::vector<std::string> walk_keys;
1312   walk_keys.push_back("walk");
1313 
1314   Err err;
1315   std::vector<Value> result;
1316   TargetSet targets;
1317   one.GetMetadata(data_keys, walk_keys, SourceDir(), false, &result, &targets,
1318                   &err);
1319   EXPECT_TRUE(err.has_error());
1320   EXPECT_EQ(err.message(),
1321             "I was expecting //foo:missing(//toolchain:default) to be a "
1322             "dependency of //foo:one(//toolchain:default). "
1323             "Make sure it's included in the deps or data_deps, and that you've "
1324             "specified the appropriate toolchain.")
1325       << err.message();
1326 }
1327 
TEST_F(TargetTest,WriteMetadataCollection)1328 TEST_F(TargetTest, WriteMetadataCollection) {
1329   TestWithScope setup;
1330   Err err;
1331 
1332   SourceFile source_file("//out/Debug/metadata.json");
1333   OutputFile output_file(setup.build_settings(), source_file);
1334 
1335   TestTarget generator(setup, "//foo:write", Target::GENERATED_FILE);
1336   generator.action_values().outputs() =
1337       SubstitutionList::MakeForTest("//out/Debug/metadata.json");
1338   EXPECT_TRUE(generator.OnResolved(&err));
1339 
1340   TestTarget middle_data_dep(setup, "//foo:middle", Target::EXECUTABLE);
1341   middle_data_dep.data_deps().push_back(LabelTargetPair(&generator));
1342   EXPECT_TRUE(middle_data_dep.OnResolved(&err));
1343 
1344   // This target has a generated metadata input and no dependency makes it.
1345   TestTarget dep_missing(setup, "//foo:no_dep", Target::EXECUTABLE);
1346   dep_missing.sources().push_back(source_file);
1347   EXPECT_TRUE(dep_missing.OnResolved(&err));
1348   AssertSchedulerHasOneUnknownFileMatching(&dep_missing, source_file);
1349   scheduler().ClearUnknownGeneratedInputsAndWrittenFiles();
1350 
1351   // This target has a generated file and we've directly dependended on it.
1352   TestTarget dep_present(setup, "//foo:with_dep", Target::EXECUTABLE);
1353   dep_present.sources().push_back(source_file);
1354   dep_present.private_deps().push_back(LabelTargetPair(&generator));
1355   EXPECT_TRUE(dep_present.OnResolved(&err));
1356   EXPECT_TRUE(scheduler().GetUnknownGeneratedInputs().empty());
1357 
1358   // This target has a generated file and we've indirectly dependended on it
1359   // via data_deps.
1360   TestTarget dep_indirect(setup, "//foo:indirect_dep", Target::EXECUTABLE);
1361   dep_indirect.sources().push_back(source_file);
1362   dep_indirect.data_deps().push_back(LabelTargetPair(&middle_data_dep));
1363   EXPECT_TRUE(dep_indirect.OnResolved(&err));
1364   AssertSchedulerHasOneUnknownFileMatching(&dep_indirect, source_file);
1365   scheduler().ClearUnknownGeneratedInputsAndWrittenFiles();
1366 
1367   // This target has a generated file and we've directly dependended on it
1368   // via data_deps.
1369   TestTarget data_dep_present(setup, "//foo:with_data_dep", Target::EXECUTABLE);
1370   data_dep_present.sources().push_back(source_file);
1371   data_dep_present.data_deps().push_back(LabelTargetPair(&generator));
1372   EXPECT_TRUE(data_dep_present.OnResolved(&err));
1373   EXPECT_TRUE(scheduler().GetUnknownGeneratedInputs().empty());
1374 }
1375 
1376 // Tests that modulemap files use the cxx_module tool.
TEST_F(TargetTest,ModuleMap)1377 TEST_F(TargetTest, ModuleMap) {
1378   TestWithScope setup;
1379 
1380   Toolchain toolchain(setup.settings(), Label(SourceDir("//tc/"), "tc"));
1381 
1382   std::unique_ptr<Tool> tool = Tool::CreateTool(CTool::kCToolCxxModule);
1383   CTool* cxx_module = tool->AsC();
1384   cxx_module->set_outputs(
1385       SubstitutionList::MakeForTest("{{source_file_part}}.pcm"));
1386   toolchain.SetTool(std::move(tool));
1387 
1388   Target target(setup.settings(), Label(SourceDir("//a/"), "a"));
1389   target.set_output_type(Target::SOURCE_SET);
1390   target.SetToolchain(&toolchain);
1391   Err err;
1392   ASSERT_TRUE(target.OnResolved(&err));
1393 
1394   const char* computed_tool_type = nullptr;
1395   std::vector<OutputFile> output;
1396   bool result = target.GetOutputFilesForSource(
1397       SourceFile("//source/input.modulemap"), &computed_tool_type, &output);
1398   ASSERT_TRUE(result);
1399   EXPECT_EQ(std::string("cxx_module"), std::string(computed_tool_type));
1400 
1401   // Outputs are relative to the build directory "//out/Debug/".
1402   ASSERT_EQ(1u, output.size());
1403   EXPECT_EQ("input.modulemap.pcm", output[0].value()) << output[0].value();
1404 }
1405