Revert 264226 "Reduce dependency of TiclInvalidationService on P..."
[chromium-blink-merge.git] / tools / gn / ninja_action_target_writer_unittest.cc
blobc1aa6f495b85ff6e845d68d9a102a013e108495c
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.
5 #include <algorithm>
6 #include <sstream>
8 #include "testing/gtest/include/gtest/gtest.h"
9 #include "tools/gn/file_template.h"
10 #include "tools/gn/ninja_action_target_writer.h"
11 #include "tools/gn/test_with_scope.h"
13 TEST(NinjaActionTargetWriter, WriteOutputFilesForBuildLine) {
14 TestWithScope setup;
15 setup.build_settings()->SetBuildDir(SourceDir("//out/Debug/"));
16 Target target(setup.settings(), Label(SourceDir("//foo/"), "bar"));
18 target.action_values().outputs().push_back(
19 SourceFile("//out/Debug/gen/a b{{source_name_part}}.h"));
20 target.action_values().outputs().push_back(
21 SourceFile("//out/Debug/gen/{{source_name_part}}.cc"));
23 std::ostringstream out;
24 NinjaActionTargetWriter writer(&target, setup.toolchain(), out);
26 FileTemplate output_template = writer.GetOutputTemplate();
28 SourceFile source("//foo/bar.in");
29 std::vector<OutputFile> output_files;
30 writer.WriteOutputFilesForBuildLine(output_template, source, &output_files);
32 std::string out_str = out.str();
33 #if defined(OS_WIN)
34 std::replace(out_str.begin(), out_str.end(), '\\', '/');
35 #endif
36 EXPECT_EQ(" gen/a$ bbar.h gen/bar.cc", out_str);
39 TEST(NinjaActionTargetWriter, WriteOutputFilesForBuildLineWithDepfile) {
40 TestWithScope setup;
41 setup.build_settings()->SetBuildDir(SourceDir("//out/Debug/"));
42 Target target(setup.settings(), Label(SourceDir("//foo/"), "bar"));
44 target.action_values().set_depfile(
45 SourceFile("//out/Debug/gen/{{source_name_part}}.d"));
46 target.action_values().outputs().push_back(
47 SourceFile("//out/Debug/gen/{{source_name_part}}.h"));
48 target.action_values().outputs().push_back(
49 SourceFile("//out/Debug/gen/{{source_name_part}}.cc"));
51 std::ostringstream out;
52 NinjaActionTargetWriter writer(&target, setup.toolchain(), out);
54 FileTemplate output_template = writer.GetOutputTemplate();
56 SourceFile source("//foo/bar.in");
57 std::vector<OutputFile> output_files;
58 writer.WriteOutputFilesForBuildLine(output_template, source, &output_files);
60 std::string out_str = out.str();
61 #if defined(OS_WIN)
62 std::replace(out_str.begin(), out_str.end(), '\\', '/');
63 #endif
64 EXPECT_EQ(" gen/bar.d gen/bar.h gen/bar.cc", out_str);
67 TEST(NinjaActionTargetWriter, WriteArgsSubstitutions) {
68 TestWithScope setup;
69 setup.build_settings()->SetBuildDir(SourceDir("//out/Debug/"));
70 Target target(setup.settings(), Label(SourceDir("//foo/"), "bar"));
72 std::ostringstream out;
73 NinjaActionTargetWriter writer(&target, setup.toolchain(), out);
75 std::vector<std::string> args;
76 args.push_back("-i");
77 args.push_back("{{source}}");
78 args.push_back("--out=foo bar{{source_name_part}}.o");
79 FileTemplate args_template(args);
81 writer.WriteArgsSubstitutions(SourceFile("//foo/b ar.in"), args_template);
83 std::string out_str = out.str();
84 #if defined(OS_WIN)
85 std::replace(out_str.begin(), out_str.end(), '\\', '/');
86 #endif
87 EXPECT_EQ(" source = ../../foo/b$ ar.in\n source_name_part = b$ ar\n",
88 out_str);
91 // Makes sure that we write sources as input dependencies for actions with
92 // both sources and source_prereqs (ACTION_FOREACH treats the sources
93 // differently).
94 TEST(NinjaActionTargetWriter, ActionWithSources) {
95 TestWithScope setup;
96 setup.build_settings()->SetBuildDir(SourceDir("//out/Debug/"));
97 Target target(setup.settings(), Label(SourceDir("//foo/"), "bar"));
98 target.set_output_type(Target::ACTION);
100 target.action_values().set_script(SourceFile("//foo/script.py"));
102 target.sources().push_back(SourceFile("//foo/source.txt"));
103 target.source_prereqs().push_back(SourceFile("//foo/included.txt"));
105 target.action_values().outputs().push_back(
106 SourceFile("//out/Debug/foo.out"));
108 // Posix.
110 setup.settings()->set_target_os(Settings::LINUX);
111 setup.build_settings()->set_python_path(base::FilePath(FILE_PATH_LITERAL(
112 "/usr/bin/python")));
114 std::ostringstream out;
115 NinjaActionTargetWriter writer(&target, setup.toolchain(), out);
116 writer.Run();
118 const char expected_linux[] =
119 "rule __foo_bar___rule\n"
120 " command = /usr/bin/python ../../foo/script.py\n"
121 " description = ACTION //foo:bar()\n"
122 " restat = 1"
123 "\n"
124 "\n"
125 "build foo.out: __foo_bar___rule | ../../foo/included.txt ../../foo/source.txt\n"
126 "\n"
127 "build obj/foo/bar.stamp: stamp foo.out\n";
128 std::string out_str = out.str();
129 #if defined(OS_WIN)
130 std::replace(out_str.begin(), out_str.end(), '\\', '/');
131 #endif
132 EXPECT_EQ(expected_linux, out_str);
135 // Windows.
137 // Note: we use forward slashes here so that the output will be the same on
138 // Linux and Windows.
139 setup.build_settings()->set_python_path(base::FilePath(FILE_PATH_LITERAL(
140 "C:/python/python.exe")));
141 setup.settings()->set_target_os(Settings::WIN);
143 std::ostringstream out;
144 NinjaActionTargetWriter writer(&target, setup.toolchain(), out);
145 writer.Run();
147 // TODO(brettw) I think we'll need to worry about backslashes here
148 // depending if we're on actual Windows or Linux pretending to be Windows.
149 const char expected_win[] =
150 "rule __foo_bar___rule\n"
151 " command = C:/python/python.exe gyp-win-tool action-wrapper environment.x86 __foo_bar___rule.$unique_name.rsp\n"
152 " description = ACTION //foo:bar()\n"
153 " restat = 1\n"
154 " rspfile = __foo_bar___rule.$unique_name.rsp\n"
155 " rspfile_content = C:/python/python.exe ../../foo/script.py\n"
156 "\n"
157 "build foo.out: __foo_bar___rule | ../../foo/included.txt ../../foo/source.txt\n"
158 "\n"
159 "build obj/foo/bar.stamp: stamp foo.out\n";
160 std::string out_str = out.str();
161 #if defined(OS_WIN)
162 std::replace(out_str.begin(), out_str.end(), '\\', '/');
163 #endif
164 EXPECT_EQ(expected_win, out_str);
168 TEST(NinjaActionTargetWriter, ForEach) {
169 TestWithScope setup;
170 setup.build_settings()->SetBuildDir(SourceDir("//out/Debug/"));
171 Target target(setup.settings(), Label(SourceDir("//foo/"), "bar"));
172 target.set_output_type(Target::ACTION_FOREACH);
174 target.sources().push_back(SourceFile("//foo/input1.txt"));
175 target.sources().push_back(SourceFile("//foo/input2.txt"));
177 target.action_values().set_script(SourceFile("//foo/script.py"));
179 target.action_values().args().push_back("-i");
180 target.action_values().args().push_back("{{source}}");
181 target.action_values().args().push_back(
182 "--out=foo bar{{source_name_part}}.o");
184 target.action_values().outputs().push_back(
185 SourceFile("//out/Debug/{{source_name_part}}.out"));
187 target.source_prereqs().push_back(SourceFile("//foo/included.txt"));
189 // Posix.
191 setup.settings()->set_target_os(Settings::LINUX);
192 setup.build_settings()->set_python_path(base::FilePath(FILE_PATH_LITERAL(
193 "/usr/bin/python")));
195 std::ostringstream out;
196 NinjaActionTargetWriter writer(&target, setup.toolchain(), out);
197 writer.Run();
199 const char expected_linux[] =
200 "rule __foo_bar___rule\n"
201 " command = /usr/bin/python ../../foo/script.py -i ${source} "
202 "\"--out=foo$ bar${source_name_part}.o\"\n"
203 " description = ACTION //foo:bar()\n"
204 " restat = 1\n"
205 "\n"
206 "build input1.out: __foo_bar___rule ../../foo/input1.txt | "
207 "../../foo/included.txt\n"
208 " source = ../../foo/input1.txt\n"
209 " source_name_part = input1\n"
210 "build input2.out: __foo_bar___rule ../../foo/input2.txt | "
211 "../../foo/included.txt\n"
212 " source = ../../foo/input2.txt\n"
213 " source_name_part = input2\n"
214 "\n"
215 "build obj/foo/bar.stamp: stamp input1.out input2.out\n";
217 std::string out_str = out.str();
218 #if defined(OS_WIN)
219 std::replace(out_str.begin(), out_str.end(), '\\', '/');
220 #endif
221 EXPECT_EQ(expected_linux, out_str);
224 // Windows.
226 // Note: we use forward slashes here so that the output will be the same on
227 // Linux and Windows.
228 setup.build_settings()->set_python_path(base::FilePath(FILE_PATH_LITERAL(
229 "C:/python/python.exe")));
230 setup.settings()->set_target_os(Settings::WIN);
232 std::ostringstream out;
233 NinjaActionTargetWriter writer(&target, setup.toolchain(), out);
234 writer.Run();
236 // TODO(brettw) I think we'll need to worry about backslashes here
237 // depending if we're on actual Windows or Linux pretending to be Windows.
238 const char expected_win[] =
239 "rule __foo_bar___rule\n"
240 " command = C:/python/python.exe gyp-win-tool action-wrapper "
241 "environment.x86 __foo_bar___rule.$unique_name.rsp\n"
242 " description = ACTION //foo:bar()\n"
243 " restat = 1\n"
244 " rspfile = __foo_bar___rule.$unique_name.rsp\n"
245 " rspfile_content = C:/python/python.exe ../../foo/script.py -i "
246 "${source} \"--out=foo$ bar${source_name_part}.o\"\n"
247 "\n"
248 "build input1.out: __foo_bar___rule ../../foo/input1.txt | "
249 "../../foo/included.txt\n"
250 " unique_name = 0\n"
251 " source = ../../foo/input1.txt\n"
252 " source_name_part = input1\n"
253 "build input2.out: __foo_bar___rule ../../foo/input2.txt | "
254 "../../foo/included.txt\n"
255 " unique_name = 1\n"
256 " source = ../../foo/input2.txt\n"
257 " source_name_part = input2\n"
258 "\n"
259 "build obj/foo/bar.stamp: stamp input1.out input2.out\n";
260 std::string out_str = out.str();
261 #if defined(OS_WIN)
262 std::replace(out_str.begin(), out_str.end(), '\\', '/');
263 #endif
264 EXPECT_EQ(expected_win, out_str);
268 TEST(NinjaActionTargetWriter, ForEachWithDepfile) {
269 TestWithScope setup;
270 setup.build_settings()->SetBuildDir(SourceDir("//out/Debug/"));
271 Target target(setup.settings(), Label(SourceDir("//foo/"), "bar"));
272 target.set_output_type(Target::ACTION_FOREACH);
274 target.sources().push_back(SourceFile("//foo/input1.txt"));
275 target.sources().push_back(SourceFile("//foo/input2.txt"));
277 target.action_values().set_script(SourceFile("//foo/script.py"));
278 target.action_values().set_depfile(
279 SourceFile("//out/Debug/gen/{{source_name_part}}.d"));
281 target.action_values().args().push_back("-i");
282 target.action_values().args().push_back("{{source}}");
283 target.action_values().args().push_back(
284 "--out=foo bar{{source_name_part}}.o");
286 target.action_values().outputs().push_back(
287 SourceFile("//out/Debug/{{source_name_part}}.out"));
289 target.source_prereqs().push_back(SourceFile("//foo/included.txt"));
291 // Posix.
293 setup.settings()->set_target_os(Settings::LINUX);
294 setup.build_settings()->set_python_path(base::FilePath(FILE_PATH_LITERAL(
295 "/usr/bin/python")));
297 std::ostringstream out;
298 NinjaActionTargetWriter writer(&target, setup.toolchain(), out);
299 writer.Run();
301 const char expected_linux[] =
302 "rule __foo_bar___rule\n"
303 " command = /usr/bin/python ../../foo/script.py -i ${source} "
304 "\"--out=foo$ bar${source_name_part}.o\"\n"
305 " description = ACTION //foo:bar()\n"
306 " restat = 1\n"
307 "\n"
308 "build gen/input1.d input1.out: __foo_bar___rule ../../foo/input1.txt"
309 " | ../../foo/included.txt\n"
310 " source = ../../foo/input1.txt\n"
311 " source_name_part = input1\n"
312 " depfile = gen/input1.d\n"
313 "build gen/input2.d input2.out: __foo_bar___rule ../../foo/input2.txt"
314 " | ../../foo/included.txt\n"
315 " source = ../../foo/input2.txt\n"
316 " source_name_part = input2\n"
317 " depfile = gen/input2.d\n"
318 "\n"
319 "build obj/foo/bar.stamp: stamp input1.out input2.out\n";
321 std::string out_str = out.str();
322 #if defined(OS_WIN)
323 std::replace(out_str.begin(), out_str.end(), '\\', '/');
324 #endif
325 EXPECT_EQ(expected_linux, out_str);
328 // Windows.
330 // Note: we use forward slashes here so that the output will be the same on
331 // Linux and Windows.
332 setup.build_settings()->set_python_path(base::FilePath(FILE_PATH_LITERAL(
333 "C:/python/python.exe")));
334 setup.settings()->set_target_os(Settings::WIN);
336 std::ostringstream out;
337 NinjaActionTargetWriter writer(&target, setup.toolchain(), out);
338 writer.Run();
340 // TODO(brettw) I think we'll need to worry about backslashes here
341 // depending if we're on actual Windows or Linux pretending to be Windows.
342 const char expected_win[] =
343 "rule __foo_bar___rule\n"
344 " command = C:/python/python.exe gyp-win-tool action-wrapper "
345 "environment.x86 __foo_bar___rule.$unique_name.rsp\n"
346 " description = ACTION //foo:bar()\n"
347 " restat = 1\n"
348 " rspfile = __foo_bar___rule.$unique_name.rsp\n"
349 " rspfile_content = C:/python/python.exe ../../foo/script.py -i "
350 "${source} \"--out=foo$ bar${source_name_part}.o\"\n"
351 "\n"
352 "build gen/input1.d input1.out: __foo_bar___rule ../../foo/input1.txt"
353 " | ../../foo/included.txt\n"
354 " unique_name = 0\n"
355 " source = ../../foo/input1.txt\n"
356 " source_name_part = input1\n"
357 " depfile = gen/input1.d\n"
358 "build gen/input2.d input2.out: __foo_bar___rule ../../foo/input2.txt"
359 " | ../../foo/included.txt\n"
360 " unique_name = 1\n"
361 " source = ../../foo/input2.txt\n"
362 " source_name_part = input2\n"
363 " depfile = gen/input2.d\n"
364 "\n"
365 "build obj/foo/bar.stamp: stamp input1.out input2.out\n";
366 std::string out_str = out.str();
367 #if defined(OS_WIN)
368 std::replace(out_str.begin(), out_str.end(), '\\', '/');
369 #endif
370 EXPECT_EQ(expected_win, out_str);