Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(493)

Side by Side Diff: tools/gn/ninja_action_target_writer_unittest.cc

Issue 429423002: Refactor GN source expansions. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Clang warning Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include <algorithm> 5 #include <algorithm>
6 #include <sstream> 6 #include <sstream>
7 7
8 #include "testing/gtest/include/gtest/gtest.h" 8 #include "testing/gtest/include/gtest/gtest.h"
9 #include "tools/gn/file_template.h"
10 #include "tools/gn/ninja_action_target_writer.h" 9 #include "tools/gn/ninja_action_target_writer.h"
10 #include "tools/gn/substitution_list.h"
11 #include "tools/gn/test_with_scope.h" 11 #include "tools/gn/test_with_scope.h"
12 12
13 TEST(NinjaActionTargetWriter, WriteOutputFilesForBuildLine) { 13 TEST(NinjaActionTargetWriter, WriteOutputFilesForBuildLine) {
14 TestWithScope setup; 14 TestWithScope setup;
15 setup.build_settings()->SetBuildDir(SourceDir("//out/Debug/")); 15 setup.build_settings()->SetBuildDir(SourceDir("//out/Debug/"));
16 Target target(setup.settings(), Label(SourceDir("//foo/"), "bar")); 16 Target target(setup.settings(), Label(SourceDir("//foo/"), "bar"));
17 17 target.action_values().outputs() = SubstitutionList::MakeForTest(
18 target.action_values().outputs().push_back( 18 "//out/Debug/gen/a b{{source_name_part}}.h",
19 "//out/Debug/gen/a b{{source_name_part}}.h");
20 target.action_values().outputs().push_back(
21 "//out/Debug/gen/{{source_name_part}}.cc"); 19 "//out/Debug/gen/{{source_name_part}}.cc");
22 20
23 std::ostringstream out; 21 std::ostringstream out;
24 NinjaActionTargetWriter writer(&target, setup.toolchain(), out); 22 NinjaActionTargetWriter writer(&target, setup.toolchain(), out);
25 23
26 FileTemplate output_template = FileTemplate::GetForTargetOutputs(&target);
27
28 SourceFile source("//foo/bar.in"); 24 SourceFile source("//foo/bar.in");
29 std::vector<OutputFile> output_files; 25 std::vector<OutputFile> output_files;
30 writer.WriteOutputFilesForBuildLine(output_template, source, &output_files); 26 writer.WriteOutputFilesForBuildLine(source, &output_files);
31 27
32 EXPECT_EQ(" gen/a$ bbar.h gen/bar.cc", out.str()); 28 EXPECT_EQ(" gen/a$ bbar.h gen/bar.cc", out.str());
33 } 29 }
34 30
35 TEST(NinjaActionTargetWriter, WriteArgsSubstitutions) {
36 TestWithScope setup;
37 setup.build_settings()->SetBuildDir(SourceDir("//out/Debug/"));
38 Target target(setup.settings(), Label(SourceDir("//foo/"), "bar"));
39
40 std::ostringstream out;
41 NinjaActionTargetWriter writer(&target, setup.toolchain(), out);
42
43 std::vector<std::string> args;
44 args.push_back("-i");
45 args.push_back("{{source}}");
46 args.push_back("--out=foo bar{{source_name_part}}.o");
47 FileTemplate args_template(setup.settings(), args,
48 FileTemplate::OUTPUT_RELATIVE,
49 setup.settings()->build_settings()->build_dir());
50
51 writer.WriteArgsSubstitutions(SourceFile("//foo/b ar.in"), args_template);
52 #if defined(OS_WIN)
53 EXPECT_EQ(" source = \"../../foo/b$ ar.in\"\n"
54 " source_name_part = \"b$ ar\"\n",
55 out.str());
56 #else
57 EXPECT_EQ(" source = ../../foo/b\\$ ar.in\n"
58 " source_name_part = b\\$ ar\n",
59 out.str());
60 #endif
61 }
62
63 // Makes sure that we write sources as input dependencies for actions with 31 // Makes sure that we write sources as input dependencies for actions with
64 // both sources and inputs (ACTION_FOREACH treats the sources differently). 32 // both sources and inputs (ACTION_FOREACH treats the sources differently).
65 TEST(NinjaActionTargetWriter, ActionWithSources) { 33 TEST(NinjaActionTargetWriter, ActionWithSources) {
66 TestWithScope setup; 34 TestWithScope setup;
67 setup.build_settings()->SetBuildDir(SourceDir("//out/Debug/")); 35 setup.build_settings()->SetBuildDir(SourceDir("//out/Debug/"));
68 Target target(setup.settings(), Label(SourceDir("//foo/"), "bar")); 36 Target target(setup.settings(), Label(SourceDir("//foo/"), "bar"));
69 target.set_output_type(Target::ACTION); 37 target.set_output_type(Target::ACTION);
70 38
71 target.action_values().set_script(SourceFile("//foo/script.py")); 39 target.action_values().set_script(SourceFile("//foo/script.py"));
72 40
73 target.sources().push_back(SourceFile("//foo/source.txt")); 41 target.sources().push_back(SourceFile("//foo/source.txt"));
74 target.inputs().push_back(SourceFile("//foo/included.txt")); 42 target.inputs().push_back(SourceFile("//foo/included.txt"));
75 43
76 target.action_values().outputs().push_back("//out/Debug/foo.out"); 44 target.action_values().outputs() =
45 SubstitutionList::MakeForTest("//out/Debug/foo.out");
77 46
78 // Posix. 47 // Posix.
79 { 48 {
80 setup.settings()->set_target_os(Settings::LINUX); 49 setup.settings()->set_target_os(Settings::LINUX);
81 setup.build_settings()->set_python_path(base::FilePath(FILE_PATH_LITERAL( 50 setup.build_settings()->set_python_path(base::FilePath(FILE_PATH_LITERAL(
82 "/usr/bin/python"))); 51 "/usr/bin/python")));
83 52
84 std::ostringstream out; 53 std::ostringstream out;
85 NinjaActionTargetWriter writer(&target, setup.toolchain(), out); 54 NinjaActionTargetWriter writer(&target, setup.toolchain(), out);
86 writer.Run(); 55 writer.Run();
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
144 Target target(setup.settings(), Label(SourceDir("//foo/"), "bar")); 113 Target target(setup.settings(), Label(SourceDir("//foo/"), "bar"));
145 target.set_output_type(Target::ACTION_FOREACH); 114 target.set_output_type(Target::ACTION_FOREACH);
146 target.deps().push_back(LabelTargetPair(&dep)); 115 target.deps().push_back(LabelTargetPair(&dep));
147 target.datadeps().push_back(LabelTargetPair(&datadep)); 116 target.datadeps().push_back(LabelTargetPair(&datadep));
148 117
149 target.sources().push_back(SourceFile("//foo/input1.txt")); 118 target.sources().push_back(SourceFile("//foo/input1.txt"));
150 target.sources().push_back(SourceFile("//foo/input2.txt")); 119 target.sources().push_back(SourceFile("//foo/input2.txt"));
151 120
152 target.action_values().set_script(SourceFile("//foo/script.py")); 121 target.action_values().set_script(SourceFile("//foo/script.py"));
153 122
154 target.action_values().args().push_back("-i"); 123 target.action_values().args() = SubstitutionList::MakeForTest(
155 target.action_values().args().push_back("{{source}}"); 124 "-i",
156 target.action_values().args().push_back( 125 "{{source}}",
157 "--out=foo bar{{source_name_part}}.o"); 126 "--out=foo bar{{source_name_part}}.o");
158 127 target.action_values().outputs() = SubstitutionList::MakeForTest(
159 target.action_values().outputs().push_back(
160 "//out/Debug/{{source_name_part}}.out"); 128 "//out/Debug/{{source_name_part}}.out");
161 129
162 target.inputs().push_back(SourceFile("//foo/included.txt")); 130 target.inputs().push_back(SourceFile("//foo/included.txt"));
163 131
164 // Posix. 132 // Posix.
165 { 133 {
166 setup.settings()->set_target_os(Settings::LINUX); 134 setup.settings()->set_target_os(Settings::LINUX);
167 setup.build_settings()->set_python_path(base::FilePath(FILE_PATH_LITERAL( 135 setup.build_settings()->set_python_path(base::FilePath(FILE_PATH_LITERAL(
168 "/usr/bin/python"))); 136 "/usr/bin/python")));
169 137
170 std::ostringstream out; 138 std::ostringstream out;
171 NinjaActionTargetWriter writer(&target, setup.toolchain(), out); 139 NinjaActionTargetWriter writer(&target, setup.toolchain(), out);
172 writer.Run(); 140 writer.Run();
173 141
174 const char expected_linux[] = 142 const char expected_linux[] =
175 "rule __foo_bar___rule\n" 143 "rule __foo_bar___rule\n"
176 " command = /usr/bin/python ../../foo/script.py -i ${source} " 144 " command = /usr/bin/python ../../foo/script.py -i ${in} "
177 // Escaping is different between Windows and Posix. 145 // Escaping is different between Windows and Posix.
178 #if defined(OS_WIN) 146 #if defined(OS_WIN)
179 "\"--out=foo$ bar${source_name_part}.o\"\n" 147 "\"--out=foo$ bar${source_name_part}.o\"\n"
180 #else 148 #else
181 "--out=foo\\$ bar${source_name_part}.o\n" 149 "--out=foo\\$ bar${source_name_part}.o\n"
182 #endif 150 #endif
183 " description = ACTION //foo:bar()\n" 151 " description = ACTION //foo:bar()\n"
184 " restat = 1\n" 152 " restat = 1\n"
185 "build obj/foo/bar.inputdeps.stamp: stamp ../../foo/script.py " 153 "build obj/foo/bar.inputdeps.stamp: stamp ../../foo/script.py "
186 "../../foo/included.txt obj/foo/dep.stamp\n" 154 "../../foo/included.txt obj/foo/dep.stamp\n"
187 "\n" 155 "\n"
188 "build input1.out: __foo_bar___rule ../../foo/input1.txt | " 156 "build input1.out: __foo_bar___rule ../../foo/input1.txt | "
189 "obj/foo/bar.inputdeps.stamp\n" 157 "obj/foo/bar.inputdeps.stamp\n"
190 " source = ../../foo/input1.txt\n"
191 " source_name_part = input1\n" 158 " source_name_part = input1\n"
192 "build input2.out: __foo_bar___rule ../../foo/input2.txt | " 159 "build input2.out: __foo_bar___rule ../../foo/input2.txt | "
193 "obj/foo/bar.inputdeps.stamp\n" 160 "obj/foo/bar.inputdeps.stamp\n"
194 " source = ../../foo/input2.txt\n"
195 " source_name_part = input2\n" 161 " source_name_part = input2\n"
196 "\n" 162 "\n"
197 "build obj/foo/bar.stamp: " 163 "build obj/foo/bar.stamp: "
198 "stamp input1.out input2.out obj/foo/datadep.stamp\n"; 164 "stamp input1.out input2.out obj/foo/datadep.stamp\n";
199 165
200 std::string out_str = out.str(); 166 std::string out_str = out.str();
201 #if defined(OS_WIN) 167 #if defined(OS_WIN)
202 std::replace(out_str.begin(), out_str.end(), '\\', '/'); 168 std::replace(out_str.begin(), out_str.end(), '\\', '/');
203 #endif 169 #endif
204 EXPECT_EQ(expected_linux, out_str); 170 EXPECT_EQ(expected_linux, out_str);
(...skipping 11 matching lines...) Expand all
216 182
217 const char expected_win[] = 183 const char expected_win[] =
218 "rule __foo_bar___rule\n" 184 "rule __foo_bar___rule\n"
219 " command = C$:/python/python.exe gyp-win-tool action-wrapper " 185 " command = C$:/python/python.exe gyp-win-tool action-wrapper "
220 "environment.x86 __foo_bar___rule.$unique_name.rsp\n" 186 "environment.x86 __foo_bar___rule.$unique_name.rsp\n"
221 " description = ACTION //foo:bar()\n" 187 " description = ACTION //foo:bar()\n"
222 " restat = 1\n" 188 " restat = 1\n"
223 " rspfile = __foo_bar___rule.$unique_name.rsp\n" 189 " rspfile = __foo_bar___rule.$unique_name.rsp\n"
224 " rspfile_content = C$:/python/python.exe ../../foo/script.py -i " 190 " rspfile_content = C$:/python/python.exe ../../foo/script.py -i "
225 #if defined(OS_WIN) 191 #if defined(OS_WIN)
226 "${source} \"--out=foo$ bar${source_name_part}.o\"\n" 192 "${in} \"--out=foo$ bar${source_name_part}.o\"\n"
227 #else 193 #else
228 "${source} --out=foo\\$ bar${source_name_part}.o\n" 194 "${in} --out=foo\\$ bar${source_name_part}.o\n"
229 #endif 195 #endif
230 "build obj/foo/bar.inputdeps.stamp: stamp ../../foo/script.py " 196 "build obj/foo/bar.inputdeps.stamp: stamp ../../foo/script.py "
231 "../../foo/included.txt obj/foo/dep.stamp\n" 197 "../../foo/included.txt obj/foo/dep.stamp\n"
232 "\n" 198 "\n"
233 "build input1.out: __foo_bar___rule ../../foo/input1.txt | " 199 "build input1.out: __foo_bar___rule ../../foo/input1.txt | "
234 "obj/foo/bar.inputdeps.stamp\n" 200 "obj/foo/bar.inputdeps.stamp\n"
235 " unique_name = 0\n" 201 " unique_name = 0\n"
236 " source = ../../foo/input1.txt\n"
237 " source_name_part = input1\n" 202 " source_name_part = input1\n"
238 "build input2.out: __foo_bar___rule ../../foo/input2.txt | " 203 "build input2.out: __foo_bar___rule ../../foo/input2.txt | "
239 "obj/foo/bar.inputdeps.stamp\n" 204 "obj/foo/bar.inputdeps.stamp\n"
240 " unique_name = 1\n" 205 " unique_name = 1\n"
241 " source = ../../foo/input2.txt\n"
242 " source_name_part = input2\n" 206 " source_name_part = input2\n"
243 "\n" 207 "\n"
244 "build obj/foo/bar.stamp: " 208 "build obj/foo/bar.stamp: "
245 "stamp input1.out input2.out obj/foo/datadep.stamp\n"; 209 "stamp input1.out input2.out obj/foo/datadep.stamp\n";
246 EXPECT_EQ(expected_win, out.str()); 210 EXPECT_EQ(expected_win, out.str());
247 } 211 }
248 } 212 }
249 213
250 TEST(NinjaActionTargetWriter, ForEachWithDepfile) { 214 TEST(NinjaActionTargetWriter, ForEachWithDepfile) {
251 TestWithScope setup; 215 TestWithScope setup;
252 setup.build_settings()->SetBuildDir(SourceDir("//out/Debug/")); 216 setup.build_settings()->SetBuildDir(SourceDir("//out/Debug/"));
253 Target target(setup.settings(), Label(SourceDir("//foo/"), "bar")); 217 Target target(setup.settings(), Label(SourceDir("//foo/"), "bar"));
254 target.set_output_type(Target::ACTION_FOREACH); 218 target.set_output_type(Target::ACTION_FOREACH);
255 219
256 target.sources().push_back(SourceFile("//foo/input1.txt")); 220 target.sources().push_back(SourceFile("//foo/input1.txt"));
257 target.sources().push_back(SourceFile("//foo/input2.txt")); 221 target.sources().push_back(SourceFile("//foo/input2.txt"));
258 222
259 target.action_values().set_script(SourceFile("//foo/script.py")); 223 target.action_values().set_script(SourceFile("//foo/script.py"));
260 target.action_values().set_depfile(
261 SourceFile("//out/Debug/gen/{{source_name_part}}.d"));
262 224
263 target.action_values().args().push_back("-i"); 225 SubstitutionPattern depfile;
264 target.action_values().args().push_back("{{source}}"); 226 Err err;
265 target.action_values().args().push_back( 227 ASSERT_TRUE(
228 depfile.Parse("//out/Debug/gen/{{source_name_part}}.d", NULL, &err));
229 target.action_values().set_depfile(depfile);
230
231 target.action_values().args() = SubstitutionList::MakeForTest(
232 "-i",
233 "{{source}}",
266 "--out=foo bar{{source_name_part}}.o"); 234 "--out=foo bar{{source_name_part}}.o");
267 235 target.action_values().outputs() = SubstitutionList::MakeForTest(
268 target.action_values().outputs().push_back(
269 "//out/Debug/{{source_name_part}}.out"); 236 "//out/Debug/{{source_name_part}}.out");
270 237
271 target.inputs().push_back(SourceFile("//foo/included.txt")); 238 target.inputs().push_back(SourceFile("//foo/included.txt"));
272 239
273 // Posix. 240 // Posix.
274 { 241 {
275 setup.settings()->set_target_os(Settings::LINUX); 242 setup.settings()->set_target_os(Settings::LINUX);
276 setup.build_settings()->set_python_path(base::FilePath(FILE_PATH_LITERAL( 243 setup.build_settings()->set_python_path(base::FilePath(FILE_PATH_LITERAL(
277 "/usr/bin/python"))); 244 "/usr/bin/python")));
278 245
279 std::ostringstream out; 246 std::ostringstream out;
280 NinjaActionTargetWriter writer(&target, setup.toolchain(), out); 247 NinjaActionTargetWriter writer(&target, setup.toolchain(), out);
281 writer.Run(); 248 writer.Run();
282 249
283 const char expected_linux[] = 250 const char expected_linux[] =
284 "rule __foo_bar___rule\n" 251 "rule __foo_bar___rule\n"
285 " command = /usr/bin/python ../../foo/script.py -i ${source} " 252 " command = /usr/bin/python ../../foo/script.py -i ${in} "
286 #if defined(OS_WIN) 253 #if defined(OS_WIN)
287 "\"--out=foo$ bar${source_name_part}.o\"\n" 254 "\"--out=foo$ bar${source_name_part}.o\"\n"
288 #else 255 #else
289 "--out=foo\\$ bar${source_name_part}.o\n" 256 "--out=foo\\$ bar${source_name_part}.o\n"
290 #endif 257 #endif
291 " description = ACTION //foo:bar()\n" 258 " description = ACTION //foo:bar()\n"
292 " restat = 1\n" 259 " restat = 1\n"
293 "build obj/foo/bar.inputdeps.stamp: stamp ../../foo/script.py " 260 "build obj/foo/bar.inputdeps.stamp: stamp ../../foo/script.py "
294 "../../foo/included.txt\n" 261 "../../foo/included.txt\n"
295 "\n" 262 "\n"
296 "build input1.out: __foo_bar___rule ../../foo/input1.txt" 263 "build input1.out: __foo_bar___rule ../../foo/input1.txt"
297 " | obj/foo/bar.inputdeps.stamp\n" 264 " | obj/foo/bar.inputdeps.stamp\n"
298 " source = ../../foo/input1.txt\n"
299 " source_name_part = input1\n" 265 " source_name_part = input1\n"
300 " depfile = gen/input1.d\n" 266 " depfile = gen/input1.d\n"
301 "build input2.out: __foo_bar___rule ../../foo/input2.txt" 267 "build input2.out: __foo_bar___rule ../../foo/input2.txt"
302 " | obj/foo/bar.inputdeps.stamp\n" 268 " | obj/foo/bar.inputdeps.stamp\n"
303 " source = ../../foo/input2.txt\n"
304 " source_name_part = input2\n" 269 " source_name_part = input2\n"
305 " depfile = gen/input2.d\n" 270 " depfile = gen/input2.d\n"
306 "\n" 271 "\n"
307 "build obj/foo/bar.stamp: stamp input1.out input2.out\n"; 272 "build obj/foo/bar.stamp: stamp input1.out input2.out\n";
308 EXPECT_EQ(expected_linux, out.str()); 273 EXPECT_EQ(expected_linux, out.str());
309 } 274 }
310 275
311 // Windows. 276 // Windows.
312 { 277 {
313 setup.build_settings()->set_python_path(base::FilePath(FILE_PATH_LITERAL( 278 setup.build_settings()->set_python_path(base::FilePath(FILE_PATH_LITERAL(
314 "C:/python/python.exe"))); 279 "C:/python/python.exe")));
315 setup.settings()->set_target_os(Settings::WIN); 280 setup.settings()->set_target_os(Settings::WIN);
316 281
317 std::ostringstream out; 282 std::ostringstream out;
318 NinjaActionTargetWriter writer(&target, setup.toolchain(), out); 283 NinjaActionTargetWriter writer(&target, setup.toolchain(), out);
319 writer.Run(); 284 writer.Run();
320 285
321 const char expected_win[] = 286 const char expected_win[] =
322 "rule __foo_bar___rule\n" 287 "rule __foo_bar___rule\n"
323 " command = C$:/python/python.exe gyp-win-tool action-wrapper " 288 " command = C$:/python/python.exe gyp-win-tool action-wrapper "
324 "environment.x86 __foo_bar___rule.$unique_name.rsp\n" 289 "environment.x86 __foo_bar___rule.$unique_name.rsp\n"
325 " description = ACTION //foo:bar()\n" 290 " description = ACTION //foo:bar()\n"
326 " restat = 1\n" 291 " restat = 1\n"
327 " rspfile = __foo_bar___rule.$unique_name.rsp\n" 292 " rspfile = __foo_bar___rule.$unique_name.rsp\n"
328 " rspfile_content = C$:/python/python.exe ../../foo/script.py -i " 293 " rspfile_content = C$:/python/python.exe ../../foo/script.py -i "
329 #if defined(OS_WIN) 294 #if defined(OS_WIN)
330 "${source} \"--out=foo$ bar${source_name_part}.o\"\n" 295 "${in} \"--out=foo$ bar${source_name_part}.o\"\n"
331 #else 296 #else
332 "${source} --out=foo\\$ bar${source_name_part}.o\n" 297 "${in} --out=foo\\$ bar${source_name_part}.o\n"
333 #endif 298 #endif
334 "build obj/foo/bar.inputdeps.stamp: stamp ../../foo/script.py " 299 "build obj/foo/bar.inputdeps.stamp: stamp ../../foo/script.py "
335 "../../foo/included.txt\n" 300 "../../foo/included.txt\n"
336 "\n" 301 "\n"
337 "build input1.out: __foo_bar___rule ../../foo/input1.txt" 302 "build input1.out: __foo_bar___rule ../../foo/input1.txt"
338 " | obj/foo/bar.inputdeps.stamp\n" 303 " | obj/foo/bar.inputdeps.stamp\n"
339 " unique_name = 0\n" 304 " unique_name = 0\n"
340 " source = ../../foo/input1.txt\n"
341 " source_name_part = input1\n" 305 " source_name_part = input1\n"
342 " depfile = gen/input1.d\n" 306 " depfile = gen/input1.d\n"
343 "build input2.out: __foo_bar___rule ../../foo/input2.txt" 307 "build input2.out: __foo_bar___rule ../../foo/input2.txt"
344 " | obj/foo/bar.inputdeps.stamp\n" 308 " | obj/foo/bar.inputdeps.stamp\n"
345 " unique_name = 1\n" 309 " unique_name = 1\n"
346 " source = ../../foo/input2.txt\n"
347 " source_name_part = input2\n" 310 " source_name_part = input2\n"
348 " depfile = gen/input2.d\n" 311 " depfile = gen/input2.d\n"
349 "\n" 312 "\n"
350 "build obj/foo/bar.stamp: stamp input1.out input2.out\n"; 313 "build obj/foo/bar.stamp: stamp input1.out input2.out\n";
351 EXPECT_EQ(expected_win, out.str()); 314 EXPECT_EQ(expected_win, out.str());
352 } 315 }
353 } 316 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698