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