Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / tools / gn / target_unittest.cc
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 "testing/gtest/include/gtest/gtest.h"
6 #include "tools/gn/build_settings.h"
7 #include "tools/gn/config.h"
8 #include "tools/gn/settings.h"
9 #include "tools/gn/target.h"
10 #include "tools/gn/test_with_scope.h"
11 #include "tools/gn/toolchain.h"
12
13 // Tests that lib[_dir]s are inherited across deps boundaries for static
14 // libraries but not executables.
15 TEST(Target, LibInheritance) {
16   TestWithScope setup;
17   Err err;
18
19   const std::string lib("foo");
20   const SourceDir libdir("/foo_dir/");
21
22   // Leaf target with ldflags set.
23   Target z(setup.settings(), Label(SourceDir("//foo/"), "z"));
24   z.set_output_type(Target::STATIC_LIBRARY);
25   z.config_values().libs().push_back(lib);
26   z.config_values().lib_dirs().push_back(libdir);
27   z.visibility().SetPublic();
28   z.SetToolchain(setup.toolchain());
29   ASSERT_TRUE(z.OnResolved(&err));
30
31   // All lib[_dir]s should be set when target is resolved.
32   ASSERT_EQ(1u, z.all_libs().size());
33   EXPECT_EQ(lib, z.all_libs()[0]);
34   ASSERT_EQ(1u, z.all_lib_dirs().size());
35   EXPECT_EQ(libdir, z.all_lib_dirs()[0]);
36
37   // Shared library target should inherit the libs from the static library
38   // and its own. Its own flag should be before the inherited one.
39   const std::string second_lib("bar");
40   const SourceDir second_libdir("/bar_dir/");
41   Target shared(setup.settings(), Label(SourceDir("//foo/"), "shared"));
42   shared.set_output_type(Target::SHARED_LIBRARY);
43   shared.config_values().libs().push_back(second_lib);
44   shared.config_values().lib_dirs().push_back(second_libdir);
45   shared.private_deps().push_back(LabelTargetPair(&z));
46   shared.visibility().SetPublic();
47   shared.SetToolchain(setup.toolchain());
48   ASSERT_TRUE(shared.OnResolved(&err));
49
50   ASSERT_EQ(2u, shared.all_libs().size());
51   EXPECT_EQ(second_lib, shared.all_libs()[0]);
52   EXPECT_EQ(lib, shared.all_libs()[1]);
53   ASSERT_EQ(2u, shared.all_lib_dirs().size());
54   EXPECT_EQ(second_libdir, shared.all_lib_dirs()[0]);
55   EXPECT_EQ(libdir, shared.all_lib_dirs()[1]);
56
57   // Executable target shouldn't get either by depending on shared.
58   Target exec(setup.settings(), Label(SourceDir("//foo/"), "exec"));
59   exec.set_output_type(Target::EXECUTABLE);
60   exec.private_deps().push_back(LabelTargetPair(&shared));
61   exec.SetToolchain(setup.toolchain());
62   ASSERT_TRUE(exec.OnResolved(&err));
63   EXPECT_EQ(0u, exec.all_libs().size());
64   EXPECT_EQ(0u, exec.all_lib_dirs().size());
65 }
66
67 // Test all_dependent_configs, public_config inheritance, and
68 // forward_dependent_configs_from
69 TEST(Target, DependentConfigs) {
70   TestWithScope setup;
71   Err err;
72
73   // Set up a dependency chain of a -> b -> c
74   Target a(setup.settings(), Label(SourceDir("//foo/"), "a"));
75   a.set_output_type(Target::EXECUTABLE);
76   a.visibility().SetPublic();
77   a.SetToolchain(setup.toolchain());
78   Target b(setup.settings(), Label(SourceDir("//foo/"), "b"));
79   b.set_output_type(Target::STATIC_LIBRARY);
80   b.visibility().SetPublic();
81   b.SetToolchain(setup.toolchain());
82   Target c(setup.settings(), Label(SourceDir("//foo/"), "c"));
83   c.set_output_type(Target::STATIC_LIBRARY);
84   c.visibility().SetPublic();
85   c.SetToolchain(setup.toolchain());
86   a.private_deps().push_back(LabelTargetPair(&b));
87   b.private_deps().push_back(LabelTargetPair(&c));
88
89   // Normal non-inherited config.
90   Config config(setup.settings(), Label(SourceDir("//foo/"), "config"));
91   c.configs().push_back(LabelConfigPair(&config));
92
93   // All dependent config.
94   Config all(setup.settings(), Label(SourceDir("//foo/"), "all"));
95   c.all_dependent_configs().push_back(LabelConfigPair(&all));
96
97   // Direct dependent config.
98   Config direct(setup.settings(), Label(SourceDir("//foo/"), "direct"));
99   c.public_configs().push_back(LabelConfigPair(&direct));
100
101   ASSERT_TRUE(c.OnResolved(&err));
102   ASSERT_TRUE(b.OnResolved(&err));
103   ASSERT_TRUE(a.OnResolved(&err));
104
105   // B should have gotten both dependent configs from C.
106   ASSERT_EQ(2u, b.configs().size());
107   EXPECT_EQ(&all, b.configs()[0].ptr);
108   EXPECT_EQ(&direct, b.configs()[1].ptr);
109   ASSERT_EQ(1u, b.all_dependent_configs().size());
110   EXPECT_EQ(&all, b.all_dependent_configs()[0].ptr);
111
112   // A should have just gotten the "all" dependent config from C.
113   ASSERT_EQ(1u, a.configs().size());
114   EXPECT_EQ(&all, a.configs()[0].ptr);
115   EXPECT_EQ(&all, a.all_dependent_configs()[0].ptr);
116
117   // Making an an alternate A and B with B forwarding the direct dependents.
118   Target a_fwd(setup.settings(), Label(SourceDir("//foo/"), "a_fwd"));
119   a_fwd.set_output_type(Target::EXECUTABLE);
120   a_fwd.visibility().SetPublic();
121   a_fwd.SetToolchain(setup.toolchain());
122   Target b_fwd(setup.settings(), Label(SourceDir("//foo/"), "b_fwd"));
123   b_fwd.set_output_type(Target::STATIC_LIBRARY);
124   b_fwd.SetToolchain(setup.toolchain());
125   b_fwd.visibility().SetPublic();
126   a_fwd.private_deps().push_back(LabelTargetPair(&b_fwd));
127   b_fwd.private_deps().push_back(LabelTargetPair(&c));
128   b_fwd.forward_dependent_configs().push_back(LabelTargetPair(&c));
129
130   ASSERT_TRUE(b_fwd.OnResolved(&err));
131   ASSERT_TRUE(a_fwd.OnResolved(&err));
132
133   // A_fwd should now have both configs.
134   ASSERT_EQ(2u, a_fwd.configs().size());
135   EXPECT_EQ(&all, a_fwd.configs()[0].ptr);
136   EXPECT_EQ(&direct, a_fwd.configs()[1].ptr);
137   ASSERT_EQ(1u, a_fwd.all_dependent_configs().size());
138   EXPECT_EQ(&all, a_fwd.all_dependent_configs()[0].ptr);
139 }
140
141 TEST(Target, InheritLibs) {
142   TestWithScope setup;
143   Err err;
144
145   // Create a dependency chain:
146   //   A (executable) -> B (shared lib) -> C (static lib) -> D (source set)
147   Target a(setup.settings(), Label(SourceDir("//foo/"), "a"));
148   a.set_output_type(Target::EXECUTABLE);
149   a.visibility().SetPublic();
150   a.SetToolchain(setup.toolchain());
151   Target b(setup.settings(), Label(SourceDir("//foo/"), "b"));
152   b.set_output_type(Target::SHARED_LIBRARY);
153   b.visibility().SetPublic();
154   b.SetToolchain(setup.toolchain());
155   Target c(setup.settings(), Label(SourceDir("//foo/"), "c"));
156   c.set_output_type(Target::STATIC_LIBRARY);
157   c.visibility().SetPublic();
158   c.SetToolchain(setup.toolchain());
159   Target d(setup.settings(), Label(SourceDir("//foo/"), "d"));
160   d.set_output_type(Target::SOURCE_SET);
161   d.visibility().SetPublic();
162   d.SetToolchain(setup.toolchain());
163   a.private_deps().push_back(LabelTargetPair(&b));
164   b.private_deps().push_back(LabelTargetPair(&c));
165   c.private_deps().push_back(LabelTargetPair(&d));
166
167   ASSERT_TRUE(d.OnResolved(&err));
168   ASSERT_TRUE(c.OnResolved(&err));
169   ASSERT_TRUE(b.OnResolved(&err));
170   ASSERT_TRUE(a.OnResolved(&err));
171
172   // C should have D in its inherited libs.
173   const UniqueVector<const Target*>& c_inherited = c.inherited_libraries();
174   EXPECT_EQ(1u, c_inherited.size());
175   EXPECT_TRUE(c_inherited.IndexOf(&d) != static_cast<size_t>(-1));
176
177   // B should have C and D in its inherited libs.
178   const UniqueVector<const Target*>& b_inherited = b.inherited_libraries();
179   EXPECT_EQ(2u, b_inherited.size());
180   EXPECT_TRUE(b_inherited.IndexOf(&c) != static_cast<size_t>(-1));
181   EXPECT_TRUE(b_inherited.IndexOf(&d) != static_cast<size_t>(-1));
182
183   // A should have B in its inherited libs, but not any others (the shared
184   // library will include the static library and source set).
185   const UniqueVector<const Target*>& a_inherited = a.inherited_libraries();
186   EXPECT_EQ(1u, a_inherited.size());
187   EXPECT_TRUE(a_inherited.IndexOf(&b) != static_cast<size_t>(-1));
188 }
189
190 TEST(Target, InheritCompleteStaticLib) {
191   TestWithScope setup;
192   Err err;
193
194   // Create a dependency chain:
195   //   A (executable) -> B (complete static lib) -> C (source set)
196   Target a(setup.settings(), Label(SourceDir("//foo/"), "a"));
197   a.set_output_type(Target::EXECUTABLE);
198   a.visibility().SetPublic();
199   a.SetToolchain(setup.toolchain());
200   Target b(setup.settings(), Label(SourceDir("//foo/"), "b"));
201   b.set_output_type(Target::STATIC_LIBRARY);
202   b.visibility().SetPublic();
203   b.set_complete_static_lib(true);
204   b.SetToolchain(setup.toolchain());
205   Target c(setup.settings(), Label(SourceDir("//foo/"), "c"));
206   c.set_output_type(Target::SOURCE_SET);
207   c.visibility().SetPublic();
208   c.SetToolchain(setup.toolchain());
209   a.public_deps().push_back(LabelTargetPair(&b));
210   b.public_deps().push_back(LabelTargetPair(&c));
211
212   ASSERT_TRUE(c.OnResolved(&err));
213   ASSERT_TRUE(b.OnResolved(&err));
214   ASSERT_TRUE(a.OnResolved(&err));
215
216   // B should have C in its inherited libs.
217   const UniqueVector<const Target*>& b_inherited = b.inherited_libraries();
218   EXPECT_EQ(1u, b_inherited.size());
219   EXPECT_TRUE(b_inherited.IndexOf(&c) != static_cast<size_t>(-1));
220
221   // A should have B in its inherited libs, but not any others (the complete
222   // static library will include the source set).
223   const UniqueVector<const Target*>& a_inherited = a.inherited_libraries();
224   EXPECT_EQ(1u, a_inherited.size());
225   EXPECT_TRUE(a_inherited.IndexOf(&b) != static_cast<size_t>(-1));
226 }
227
228 TEST(Target, InheritCompleteStaticLibNoDirectStaticLibDeps) {
229   TestWithScope setup;
230   Err err;
231
232   // Create a dependency chain:
233   //   A (complete static lib) -> B (static lib)
234   Target a(setup.settings(), Label(SourceDir("//foo/"), "a"));
235   a.set_output_type(Target::STATIC_LIBRARY);
236   a.visibility().SetPublic();
237   a.set_complete_static_lib(true);
238   a.SetToolchain(setup.toolchain());
239   Target b(setup.settings(), Label(SourceDir("//foo/"), "b"));
240   b.set_output_type(Target::STATIC_LIBRARY);
241   b.visibility().SetPublic();
242   b.SetToolchain(setup.toolchain());
243
244   a.public_deps().push_back(LabelTargetPair(&b));
245   ASSERT_TRUE(b.OnResolved(&err));
246   ASSERT_FALSE(a.OnResolved(&err));
247 }
248
249 TEST(Target, InheritCompleteStaticLibNoIheritedStaticLibDeps) {
250   TestWithScope setup;
251   Err err;
252
253   // Create a dependency chain:
254   //   A (complete static lib) -> B (source set) -> C (static lib)
255   Target a(setup.settings(), Label(SourceDir("//foo/"), "a"));
256   a.set_output_type(Target::STATIC_LIBRARY);
257   a.visibility().SetPublic();
258   a.set_complete_static_lib(true);
259   a.SetToolchain(setup.toolchain());
260   Target b(setup.settings(), Label(SourceDir("//foo/"), "b"));
261   b.set_output_type(Target::SOURCE_SET);
262   b.visibility().SetPublic();
263   b.SetToolchain(setup.toolchain());
264   Target c(setup.settings(), Label(SourceDir("//foo/"), "c"));
265   c.set_output_type(Target::STATIC_LIBRARY);
266   c.visibility().SetPublic();
267   c.SetToolchain(setup.toolchain());
268
269   a.public_deps().push_back(LabelTargetPair(&b));
270   b.public_deps().push_back(LabelTargetPair(&c));
271
272   ASSERT_TRUE(c.OnResolved(&err));
273   ASSERT_TRUE(b.OnResolved(&err));
274   ASSERT_FALSE(a.OnResolved(&err));
275 }
276
277 TEST(Target, GetComputedOutputName) {
278   TestWithScope setup;
279   Err err;
280
281   // Basic target with no prefix (executable type tool in the TestWithScope has
282   // no prefix) or output name.
283   Target basic(setup.settings(), Label(SourceDir("//foo/"), "bar"));
284   basic.set_output_type(Target::EXECUTABLE);
285   basic.SetToolchain(setup.toolchain());
286   ASSERT_TRUE(basic.OnResolved(&err));
287   EXPECT_EQ("bar", basic.GetComputedOutputName(false));
288   EXPECT_EQ("bar", basic.GetComputedOutputName(true));
289
290   // Target with no prefix but an output name.
291   Target with_name(setup.settings(), Label(SourceDir("//foo/"), "bar"));
292   with_name.set_output_type(Target::EXECUTABLE);
293   with_name.set_output_name("myoutput");
294   with_name.SetToolchain(setup.toolchain());
295   ASSERT_TRUE(with_name.OnResolved(&err));
296   EXPECT_EQ("myoutput", with_name.GetComputedOutputName(false));
297   EXPECT_EQ("myoutput", with_name.GetComputedOutputName(true));
298
299   // Target with a "lib" prefix (the static library tool in the TestWithScope
300   // should specify a "lib" output prefix).
301   Target with_prefix(setup.settings(), Label(SourceDir("//foo/"), "bar"));
302   with_prefix.set_output_type(Target::STATIC_LIBRARY);
303   with_prefix.SetToolchain(setup.toolchain());
304   ASSERT_TRUE(with_prefix.OnResolved(&err));
305   EXPECT_EQ("bar", with_prefix.GetComputedOutputName(false));
306   EXPECT_EQ("libbar", with_prefix.GetComputedOutputName(true));
307
308   // Target with a "lib" prefix that already has it applied. The prefix should
309   // not duplicate something already in the target name.
310   Target dup_prefix(setup.settings(), Label(SourceDir("//foo/"), "bar"));
311   dup_prefix.set_output_type(Target::STATIC_LIBRARY);
312   dup_prefix.set_output_name("libbar");
313   dup_prefix.SetToolchain(setup.toolchain());
314   ASSERT_TRUE(dup_prefix.OnResolved(&err));
315   EXPECT_EQ("libbar", dup_prefix.GetComputedOutputName(false));
316   EXPECT_EQ("libbar", dup_prefix.GetComputedOutputName(true));
317 }
318
319 // Test visibility failure case.
320 TEST(Target, VisibilityFails) {
321   TestWithScope setup;
322   Err err;
323
324   Target b(setup.settings(), Label(SourceDir("//private/"), "b"));
325   b.set_output_type(Target::STATIC_LIBRARY);
326   b.SetToolchain(setup.toolchain());
327   b.visibility().SetPrivate(b.label().dir());
328   ASSERT_TRUE(b.OnResolved(&err));
329
330   // Make a target depending on "b". The dependency must have an origin to mark
331   // it as user-set so we check visibility. This check should fail.
332   Target a(setup.settings(), Label(SourceDir("//app/"), "a"));
333   a.set_output_type(Target::EXECUTABLE);
334   a.private_deps().push_back(LabelTargetPair(&b));
335   IdentifierNode origin;  // Dummy origin.
336   a.private_deps()[0].origin = &origin;
337   a.SetToolchain(setup.toolchain());
338   ASSERT_FALSE(a.OnResolved(&err));
339 }
340
341 // Test visibility with a single data_dep.
342 TEST(Target, VisibilityDatadeps) {
343   TestWithScope setup;
344   Err err;
345
346   Target b(setup.settings(), Label(SourceDir("//public/"), "b"));
347   b.set_output_type(Target::STATIC_LIBRARY);
348   b.SetToolchain(setup.toolchain());
349   b.visibility().SetPublic();
350   ASSERT_TRUE(b.OnResolved(&err));
351
352   // Make a target depending on "b". The dependency must have an origin to mark
353   // it as user-set so we check visibility. This check should fail.
354   Target a(setup.settings(), Label(SourceDir("//app/"), "a"));
355   a.set_output_type(Target::EXECUTABLE);
356   a.data_deps().push_back(LabelTargetPair(&b));
357   IdentifierNode origin;  // Dummy origin.
358   a.data_deps()[0].origin = &origin;
359   a.SetToolchain(setup.toolchain());
360   ASSERT_TRUE(a.OnResolved(&err)) << err.help_text();
361 }
362
363 // Tests that A -> Group -> B where the group is visible from A but B isn't,
364 // passes visibility even though the group's deps get expanded into A.
365 TEST(Target, VisibilityGroup) {
366   TestWithScope setup;
367   Err err;
368
369   IdentifierNode origin;  // Dummy origin.
370
371   // B has private visibility. This lets the group see it since the group is in
372   // the same directory.
373   Target b(setup.settings(), Label(SourceDir("//private/"), "b"));
374   b.set_output_type(Target::STATIC_LIBRARY);
375   b.SetToolchain(setup.toolchain());
376   b.visibility().SetPrivate(b.label().dir());
377   ASSERT_TRUE(b.OnResolved(&err));
378
379   // The group has public visibility and depends on b.
380   Target g(setup.settings(), Label(SourceDir("//private/"), "g"));
381   g.set_output_type(Target::GROUP);
382   g.SetToolchain(setup.toolchain());
383   g.private_deps().push_back(LabelTargetPair(&b));
384   g.private_deps()[0].origin = &origin;
385   g.visibility().SetPublic();
386   ASSERT_TRUE(b.OnResolved(&err));
387
388   // Make a target depending on "g". This should succeed.
389   Target a(setup.settings(), Label(SourceDir("//app/"), "a"));
390   a.set_output_type(Target::EXECUTABLE);
391   a.private_deps().push_back(LabelTargetPair(&g));
392   a.private_deps()[0].origin = &origin;
393   a.SetToolchain(setup.toolchain());
394   ASSERT_TRUE(a.OnResolved(&err));
395 }
396
397 // Verifies that only testonly targets can depend on other testonly targets.
398 // Many of the above dependency checking cases covered the non-testonly
399 // case.
400 TEST(Target, Testonly) {
401   TestWithScope setup;
402   Err err;
403
404   // "testlib" is a test-only library.
405   Target testlib(setup.settings(), Label(SourceDir("//test/"), "testlib"));
406   testlib.set_testonly(true);
407   testlib.set_output_type(Target::STATIC_LIBRARY);
408   testlib.visibility().SetPublic();
409   testlib.SetToolchain(setup.toolchain());
410   ASSERT_TRUE(testlib.OnResolved(&err));
411
412   // "test" is a test-only executable depending on testlib, this is OK.
413   Target test(setup.settings(), Label(SourceDir("//test/"), "test"));
414   test.set_testonly(true);
415   test.set_output_type(Target::EXECUTABLE);
416   test.private_deps().push_back(LabelTargetPair(&testlib));
417   test.SetToolchain(setup.toolchain());
418   ASSERT_TRUE(test.OnResolved(&err));
419
420   // "product" is a non-test depending on testlib. This should fail.
421   Target product(setup.settings(), Label(SourceDir("//app/"), "product"));
422   product.set_testonly(false);
423   product.set_output_type(Target::EXECUTABLE);
424   product.private_deps().push_back(LabelTargetPair(&testlib));
425   product.SetToolchain(setup.toolchain());
426   ASSERT_FALSE(product.OnResolved(&err));
427 }
428
429 TEST(Target, PublicConfigs) {
430   TestWithScope setup;
431   Err err;
432
433   Label pub_config_label(SourceDir("//a/"), "pubconfig");
434   Config pub_config(setup.settings(), pub_config_label);
435
436   // This is the destination target that has a public config.
437   Target dest(setup.settings(), Label(SourceDir("//a/"), "a"));
438   dest.set_output_type(Target::SOURCE_SET);
439   dest.visibility().SetPublic();
440   dest.SetToolchain(setup.toolchain());
441   dest.public_configs().push_back(LabelConfigPair(&pub_config));
442   ASSERT_TRUE(dest.OnResolved(&err));
443
444   // This target has a public dependency on dest.
445   Target pub(setup.settings(), Label(SourceDir("//a/"), "pub"));
446   pub.set_output_type(Target::SOURCE_SET);
447   pub.visibility().SetPublic();
448   pub.SetToolchain(setup.toolchain());
449   pub.public_deps().push_back(LabelTargetPair(&dest));
450   ASSERT_TRUE(pub.OnResolved(&err));
451
452   // Depending on the target with the public dependency should forward dest's
453   // to the current target.
454   Target dep_on_pub(setup.settings(), Label(SourceDir("//a/"), "dop"));
455   dep_on_pub.set_output_type(Target::SOURCE_SET);
456   dep_on_pub.visibility().SetPublic();
457   dep_on_pub.SetToolchain(setup.toolchain());
458   dep_on_pub.private_deps().push_back(LabelTargetPair(&pub));
459   ASSERT_TRUE(dep_on_pub.OnResolved(&err));
460   ASSERT_EQ(1u, dep_on_pub.configs().size());
461   EXPECT_EQ(&pub_config, dep_on_pub.configs()[0].ptr);
462
463   // This target has a private dependency on dest for forwards configs.
464   Target forward(setup.settings(), Label(SourceDir("//a/"), "f"));
465   forward.set_output_type(Target::SOURCE_SET);
466   forward.visibility().SetPublic();
467   forward.SetToolchain(setup.toolchain());
468   forward.private_deps().push_back(LabelTargetPair(&dest));
469   forward.forward_dependent_configs().push_back(LabelTargetPair(&dest));
470   ASSERT_TRUE(forward.OnResolved(&err));
471
472   // Depending on the forward target should apply the config.
473   Target dep_on_forward(setup.settings(), Label(SourceDir("//a/"), "dof"));
474   dep_on_forward.set_output_type(Target::SOURCE_SET);
475   dep_on_forward.visibility().SetPublic();
476   dep_on_forward.SetToolchain(setup.toolchain());
477   dep_on_forward.private_deps().push_back(LabelTargetPair(&forward));
478   ASSERT_TRUE(dep_on_forward.OnResolved(&err));
479   ASSERT_EQ(1u, dep_on_forward.configs().size());
480   EXPECT_EQ(&pub_config, dep_on_forward.configs()[0].ptr);
481 }
482
483 // Tests that different link/depend outputs work for solink tools.
484 TEST(Target, LinkAndDepOutputs) {
485   TestWithScope setup;
486   Err err;
487
488   Toolchain toolchain(setup.settings(), Label(SourceDir("//tc/"), "tc"));
489
490   scoped_ptr<Tool> solink_tool(new Tool());
491   solink_tool->set_output_prefix("lib");
492   solink_tool->set_default_output_extension(".so");
493
494   const char kLinkPattern[] =
495       "{{root_out_dir}}/{{target_output_name}}{{output_extension}}";
496   SubstitutionPattern link_output = SubstitutionPattern::MakeForTest(
497       kLinkPattern);
498   solink_tool->set_link_output(link_output);
499
500   const char kDependPattern[] =
501       "{{root_out_dir}}/{{target_output_name}}{{output_extension}}.TOC";
502   SubstitutionPattern depend_output = SubstitutionPattern::MakeForTest(
503       kDependPattern);
504   solink_tool->set_depend_output(depend_output);
505
506   solink_tool->set_outputs(SubstitutionList::MakeForTest(
507       kLinkPattern, kDependPattern));
508
509   toolchain.SetTool(Toolchain::TYPE_SOLINK, solink_tool.Pass());
510
511   Target target(setup.settings(), Label(SourceDir("//a/"), "a"));
512   target.set_output_type(Target::SHARED_LIBRARY);
513   target.SetToolchain(&toolchain);
514   ASSERT_TRUE(target.OnResolved(&err));
515
516   EXPECT_EQ("./liba.so", target.link_output_file().value());
517   EXPECT_EQ("./liba.so.TOC", target.dependency_output_file().value());
518 }