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.
15TEST(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
69TEST(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
141TEST(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
190TEST(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
228TEST(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
249TEST(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
277TEST(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.
320TEST(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.
342TEST(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.
365TEST(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.
400TEST(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
429TEST(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.
484TEST(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}
519