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.
7 #include "testing/gtest/include/gtest/gtest.h"
8 #include "tools/gn/ninja_binary_target_writer.h"
9 #include "tools/gn/target.h"
10 #include "tools/gn/test_with_scope.h"
12 TEST(NinjaBinaryTargetWriter
, SourceSet
) {
16 setup
.build_settings()->SetBuildDir(SourceDir("//out/Debug/"));
17 setup
.settings()->set_target_os(Settings::WIN
);
19 Target
target(setup
.settings(), Label(SourceDir("//foo/"), "bar"));
20 target
.set_output_type(Target::SOURCE_SET
);
21 target
.visibility().SetPublic();
22 target
.sources().push_back(SourceFile("//foo/input1.cc"));
23 target
.sources().push_back(SourceFile("//foo/input2.cc"));
24 // Also test object files, which should be just passed through to the
25 // dependents to link.
26 target
.sources().push_back(SourceFile("//foo/input3.o"));
27 target
.sources().push_back(SourceFile("//foo/input4.obj"));
28 target
.SetToolchain(setup
.toolchain());
29 ASSERT_TRUE(target
.OnResolved(&err
));
33 std::ostringstream out
;
34 NinjaBinaryTargetWriter
writer(&target
, out
);
37 const char expected
[] =
46 "target_out_dir = obj/foo\n"
47 "target_output_name = bar\n"
49 "build obj/foo/bar.input1.o: cxx ../../foo/input1.cc\n"
50 "build obj/foo/bar.input2.o: cxx ../../foo/input2.cc\n"
52 "build obj/foo/bar.stamp: stamp obj/foo/bar.input1.o "
53 "obj/foo/bar.input2.o ../../foo/input3.o ../../foo/input4.obj\n";
54 std::string out_str
= out
.str();
55 EXPECT_EQ(expected
, out_str
);
58 // A shared library that depends on the source set.
59 Target
shlib_target(setup
.settings(), Label(SourceDir("//foo/"), "shlib"));
60 shlib_target
.set_output_type(Target::SHARED_LIBRARY
);
61 shlib_target
.public_deps().push_back(LabelTargetPair(&target
));
62 shlib_target
.SetToolchain(setup
.toolchain());
63 ASSERT_TRUE(shlib_target
.OnResolved(&err
));
66 std::ostringstream out
;
67 NinjaBinaryTargetWriter
writer(&shlib_target
, out
);
70 const char expected
[] =
79 "target_out_dir = obj/foo\n"
80 "target_output_name = libshlib\n"
83 // Ordering of the obj files here should come out in the order
84 // specified, with the target's first, followed by the source set's, in
86 "build ./libshlib.so: solink obj/foo/bar.input1.o "
87 "obj/foo/bar.input2.o ../../foo/input3.o ../../foo/input4.obj\n"
90 " output_extension = .so\n";
91 std::string out_str
= out
.str();
92 EXPECT_EQ(expected
, out_str
);
95 // A static library that depends on the source set (should not link it).
96 Target
stlib_target(setup
.settings(), Label(SourceDir("//foo/"), "stlib"));
97 stlib_target
.set_output_type(Target::STATIC_LIBRARY
);
98 stlib_target
.public_deps().push_back(LabelTargetPair(&target
));
99 stlib_target
.SetToolchain(setup
.toolchain());
100 ASSERT_TRUE(stlib_target
.OnResolved(&err
));
103 std::ostringstream out
;
104 NinjaBinaryTargetWriter
writer(&stlib_target
, out
);
107 const char expected
[] =
116 "target_out_dir = obj/foo\n"
117 "target_output_name = libstlib\n"
120 // There are no sources so there are no params to alink. (In practice
121 // this will probably fail in the archive tool.)
122 "build obj/foo/libstlib.a: alink\n"
125 " output_extension = \n";
126 std::string out_str
= out
.str();
127 EXPECT_EQ(expected
, out_str
);
130 // Make the static library 'complete', which means it should be linked.
131 stlib_target
.set_complete_static_lib(true);
133 std::ostringstream out
;
134 NinjaBinaryTargetWriter
writer(&stlib_target
, out
);
137 const char expected
[] =
146 "target_out_dir = obj/foo\n"
147 "target_output_name = libstlib\n"
150 // Ordering of the obj files here should come out in the order
151 // specified, with the target's first, followed by the source set's, in
153 "build obj/foo/libstlib.a: alink obj/foo/bar.input1.o "
154 "obj/foo/bar.input2.o ../../foo/input3.o ../../foo/input4.obj\n"
157 " output_extension = \n";
158 std::string out_str
= out
.str();
159 EXPECT_EQ(expected
, out_str
);
163 // This tests that output extension overrides apply, and input dependencies
165 TEST(NinjaBinaryTargetWriter
, ProductExtensionAndInputDeps
) {
169 setup
.build_settings()->SetBuildDir(SourceDir("//out/Debug/"));
170 setup
.settings()->set_target_os(Settings::LINUX
);
172 // An action for our library to depend on.
173 Target
action(setup
.settings(), Label(SourceDir("//foo/"), "action"));
174 action
.set_output_type(Target::ACTION_FOREACH
);
175 action
.visibility().SetPublic();
176 action
.SetToolchain(setup
.toolchain());
177 ASSERT_TRUE(action
.OnResolved(&err
));
179 // A shared library w/ the product_extension set to a custom value.
180 Target
target(setup
.settings(), Label(SourceDir("//foo/"), "shlib"));
181 target
.set_output_type(Target::SHARED_LIBRARY
);
182 target
.set_output_extension(std::string("so.6"));
183 target
.sources().push_back(SourceFile("//foo/input1.cc"));
184 target
.sources().push_back(SourceFile("//foo/input2.cc"));
185 target
.public_deps().push_back(LabelTargetPair(&action
));
186 target
.SetToolchain(setup
.toolchain());
187 ASSERT_TRUE(target
.OnResolved(&err
));
189 std::ostringstream out
;
190 NinjaBinaryTargetWriter
writer(&target
, out
);
193 const char expected
[] =
202 "target_out_dir = obj/foo\n"
203 "target_output_name = libshlib\n"
205 "build obj/foo/shlib.inputdeps.stamp: stamp obj/foo/action.stamp\n"
206 "build obj/foo/libshlib.input1.o: cxx ../../foo/input1.cc"
207 " || obj/foo/shlib.inputdeps.stamp\n"
208 "build obj/foo/libshlib.input2.o: cxx ../../foo/input2.cc"
209 " || obj/foo/shlib.inputdeps.stamp\n"
211 "build ./libshlib.so.6: solink obj/foo/libshlib.input1.o "
212 // The order-only dependency here is stricly unnecessary since the
213 // sources list this as an order-only dep. See discussion in the code
215 "obj/foo/libshlib.input2.o || obj/foo/action.stamp\n"
218 " output_extension = .so.6\n";
220 std::string out_str
= out
.str();
221 EXPECT_EQ(expected
, out_str
);
224 TEST(NinjaBinaryTargetWriter
, EmptyProductExtension
) {
228 setup
.build_settings()->SetBuildDir(SourceDir("//out/Debug/"));
229 setup
.settings()->set_target_os(Settings::LINUX
);
231 // This test is the same as ProductExtension, except that
232 // we call set_output_extension("") and ensure that we still get the default.
233 Target
target(setup
.settings(), Label(SourceDir("//foo/"), "shlib"));
234 target
.set_output_type(Target::SHARED_LIBRARY
);
235 target
.set_output_extension(std::string());
236 target
.sources().push_back(SourceFile("//foo/input1.cc"));
237 target
.sources().push_back(SourceFile("//foo/input2.cc"));
239 target
.SetToolchain(setup
.toolchain());
240 ASSERT_TRUE(target
.OnResolved(&err
));
242 std::ostringstream out
;
243 NinjaBinaryTargetWriter
writer(&target
, out
);
246 const char expected
[] =
255 "target_out_dir = obj/foo\n"
256 "target_output_name = libshlib\n"
258 "build obj/foo/libshlib.input1.o: cxx ../../foo/input1.cc\n"
259 "build obj/foo/libshlib.input2.o: cxx ../../foo/input2.cc\n"
261 "build ./libshlib.so: solink obj/foo/libshlib.input1.o "
262 "obj/foo/libshlib.input2.o\n"
265 " output_extension = .so\n";
267 std::string out_str
= out
.str();
268 EXPECT_EQ(expected
, out_str
);