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