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