OLD | NEW |
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/ninja_action_target_writer.h" | 9 #include "tools/gn/ninja_action_target_writer.h" |
10 #include "tools/gn/substitution_list.h" | 10 #include "tools/gn/substitution_list.h" |
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
133 | 133 |
134 target.sources().push_back(SourceFile("//foo/source.txt")); | 134 target.sources().push_back(SourceFile("//foo/source.txt")); |
135 target.inputs().push_back(SourceFile("//foo/included.txt")); | 135 target.inputs().push_back(SourceFile("//foo/included.txt")); |
136 | 136 |
137 target.action_values().outputs() = | 137 target.action_values().outputs() = |
138 SubstitutionList::MakeForTest("//out/Debug/foo.out"); | 138 SubstitutionList::MakeForTest("//out/Debug/foo.out"); |
139 | 139 |
140 target.SetToolchain(setup.toolchain()); | 140 target.SetToolchain(setup.toolchain()); |
141 ASSERT_TRUE(target.OnResolved(&err)); | 141 ASSERT_TRUE(target.OnResolved(&err)); |
142 | 142 |
143 // Posix. | 143 setup.settings()->set_target_os(Settings::LINUX); |
144 { | 144 setup.build_settings()->set_python_path(base::FilePath(FILE_PATH_LITERAL( |
145 setup.settings()->set_target_os(Settings::LINUX); | 145 "/usr/bin/python"))); |
146 setup.build_settings()->set_python_path(base::FilePath(FILE_PATH_LITERAL( | |
147 "/usr/bin/python"))); | |
148 | 146 |
149 std::ostringstream out; | 147 std::ostringstream out; |
150 NinjaActionTargetWriter writer(&target, out); | 148 NinjaActionTargetWriter writer(&target, out); |
151 writer.Run(); | 149 writer.Run(); |
152 | 150 |
153 const char expected_linux[] = | 151 const char expected_linux[] = |
154 "rule __foo_bar___rule\n" | 152 "rule __foo_bar___rule\n" |
155 " command = /usr/bin/python ../../foo/script.py\n" | 153 " command = /usr/bin/python ../../foo/script.py\n" |
156 " description = ACTION //foo:bar()\n" | 154 " description = ACTION //foo:bar()\n" |
157 " restat = 1\n" | 155 " restat = 1\n" |
158 "build obj/foo/bar.inputdeps.stamp: stamp ../../foo/script.py " | 156 "build obj/foo/bar.inputdeps.stamp: stamp ../../foo/script.py " |
159 "../../foo/included.txt ../../foo/source.txt\n" | 157 "../../foo/included.txt ../../foo/source.txt\n" |
160 "\n" | 158 "\n" |
161 "build foo.out: __foo_bar___rule | obj/foo/bar.inputdeps.stamp\n" | 159 "build foo.out: __foo_bar___rule | obj/foo/bar.inputdeps.stamp\n" |
162 "\n" | 160 "\n" |
163 "build obj/foo/bar.stamp: stamp foo.out\n"; | 161 "build obj/foo/bar.stamp: stamp foo.out\n"; |
164 EXPECT_EQ(expected_linux, out.str()); | 162 EXPECT_EQ(expected_linux, out.str()); |
165 } | |
166 | |
167 // Windows. | |
168 { | |
169 // Note: we use forward slashes here so that the output will be the same on | |
170 // Linux and Windows. | |
171 setup.build_settings()->set_python_path(base::FilePath(FILE_PATH_LITERAL( | |
172 "C:/python/python.exe"))); | |
173 setup.settings()->set_target_os(Settings::WIN); | |
174 | |
175 std::ostringstream out; | |
176 NinjaActionTargetWriter writer(&target, out); | |
177 writer.Run(); | |
178 | |
179 const char expected_win[] = | |
180 "rule __foo_bar___rule\n" | |
181 " command = C$:/python/python.exe gyp-win-tool action-wrapper environme
nt.x86 __foo_bar___rule.$unique_name.rsp\n" | |
182 " description = ACTION //foo:bar()\n" | |
183 " restat = 1\n" | |
184 " rspfile = __foo_bar___rule.$unique_name.rsp\n" | |
185 " rspfile_content = C$:/python/python.exe ../../foo/script.py\n" | |
186 "build obj/foo/bar.inputdeps.stamp: stamp ../../foo/script.py " | |
187 "../../foo/included.txt ../../foo/source.txt\n" | |
188 "\n" | |
189 "build foo.out: __foo_bar___rule | obj/foo/bar.inputdeps.stamp\n" | |
190 "\n" | |
191 "build obj/foo/bar.stamp: stamp foo.out\n"; | |
192 EXPECT_EQ(expected_win, out.str()); | |
193 } | |
194 } | 163 } |
195 | 164 |
196 TEST(NinjaActionTargetWriter, ForEach) { | 165 TEST(NinjaActionTargetWriter, ForEach) { |
197 TestWithScope setup; | 166 TestWithScope setup; |
198 Err err; | 167 Err err; |
199 | 168 |
200 setup.build_settings()->SetBuildDir(SourceDir("//out/Debug/")); | 169 setup.build_settings()->SetBuildDir(SourceDir("//out/Debug/")); |
201 | 170 |
202 // Some dependencies that the action can depend on. Use actions for these | 171 // Some dependencies that the action can depend on. Use actions for these |
203 // so they have a nice platform-independent stamp file that can appear in the | 172 // so they have a nice platform-independent stamp file that can appear in the |
(...skipping 26 matching lines...) Expand all Loading... |
230 "{{source}}", | 199 "{{source}}", |
231 "--out=foo bar{{source_name_part}}.o"); | 200 "--out=foo bar{{source_name_part}}.o"); |
232 target.action_values().outputs() = SubstitutionList::MakeForTest( | 201 target.action_values().outputs() = SubstitutionList::MakeForTest( |
233 "//out/Debug/{{source_name_part}}.out"); | 202 "//out/Debug/{{source_name_part}}.out"); |
234 | 203 |
235 target.inputs().push_back(SourceFile("//foo/included.txt")); | 204 target.inputs().push_back(SourceFile("//foo/included.txt")); |
236 | 205 |
237 target.SetToolchain(setup.toolchain()); | 206 target.SetToolchain(setup.toolchain()); |
238 ASSERT_TRUE(target.OnResolved(&err)); | 207 ASSERT_TRUE(target.OnResolved(&err)); |
239 | 208 |
240 // Posix. | 209 setup.settings()->set_target_os(Settings::LINUX); |
241 { | 210 setup.build_settings()->set_python_path(base::FilePath(FILE_PATH_LITERAL( |
242 setup.settings()->set_target_os(Settings::LINUX); | 211 "/usr/bin/python"))); |
243 setup.build_settings()->set_python_path(base::FilePath(FILE_PATH_LITERAL( | |
244 "/usr/bin/python"))); | |
245 | 212 |
246 std::ostringstream out; | 213 std::ostringstream out; |
247 NinjaActionTargetWriter writer(&target, out); | 214 NinjaActionTargetWriter writer(&target, out); |
248 writer.Run(); | 215 writer.Run(); |
249 | 216 |
250 const char expected_linux[] = | 217 const char expected_linux[] = |
251 "rule __foo_bar___rule\n" | 218 "rule __foo_bar___rule\n" |
252 " command = /usr/bin/python ../../foo/script.py -i ${in} " | 219 " command = /usr/bin/python ../../foo/script.py -i ${in} " |
253 // Escaping is different between Windows and Posix. | 220 // Escaping is different between Windows and Posix. |
254 #if defined(OS_WIN) | 221 #if defined(OS_WIN) |
255 "\"--out=foo$ bar${source_name_part}.o\"\n" | 222 "\"--out=foo$ bar${source_name_part}.o\"\n" |
256 #else | 223 #else |
257 "--out=foo\\$ bar${source_name_part}.o\n" | 224 "--out=foo\\$ bar${source_name_part}.o\n" |
258 #endif | 225 #endif |
259 " description = ACTION //foo:bar()\n" | 226 " description = ACTION //foo:bar()\n" |
260 " restat = 1\n" | 227 " restat = 1\n" |
261 "build obj/foo/bar.inputdeps.stamp: stamp ../../foo/script.py " | 228 "build obj/foo/bar.inputdeps.stamp: stamp ../../foo/script.py " |
262 "../../foo/included.txt obj/foo/dep.stamp\n" | 229 "../../foo/included.txt obj/foo/dep.stamp\n" |
263 "\n" | 230 "\n" |
264 "build input1.out: __foo_bar___rule ../../foo/input1.txt | " | 231 "build input1.out: __foo_bar___rule ../../foo/input1.txt | " |
265 "obj/foo/bar.inputdeps.stamp\n" | 232 "obj/foo/bar.inputdeps.stamp\n" |
266 " source_name_part = input1\n" | 233 " source_name_part = input1\n" |
267 "build input2.out: __foo_bar___rule ../../foo/input2.txt | " | 234 "build input2.out: __foo_bar___rule ../../foo/input2.txt | " |
268 "obj/foo/bar.inputdeps.stamp\n" | 235 "obj/foo/bar.inputdeps.stamp\n" |
269 " source_name_part = input2\n" | 236 " source_name_part = input2\n" |
270 "\n" | 237 "\n" |
271 "build obj/foo/bar.stamp: " | 238 "build obj/foo/bar.stamp: " |
272 "stamp input1.out input2.out || obj/foo/datadep.stamp\n"; | 239 "stamp input1.out input2.out || obj/foo/datadep.stamp\n"; |
273 | 240 |
274 std::string out_str = out.str(); | 241 std::string out_str = out.str(); |
275 #if defined(OS_WIN) | 242 #if defined(OS_WIN) |
276 std::replace(out_str.begin(), out_str.end(), '\\', '/'); | 243 std::replace(out_str.begin(), out_str.end(), '\\', '/'); |
277 #endif | 244 #endif |
278 EXPECT_EQ(expected_linux, out_str); | 245 EXPECT_EQ(expected_linux, out_str); |
279 } | |
280 | |
281 // Windows. | |
282 { | |
283 setup.build_settings()->set_python_path(base::FilePath(FILE_PATH_LITERAL( | |
284 "C:/python/python.exe"))); | |
285 setup.settings()->set_target_os(Settings::WIN); | |
286 | |
287 std::ostringstream out; | |
288 NinjaActionTargetWriter writer(&target, out); | |
289 writer.Run(); | |
290 | |
291 const char expected_win[] = | |
292 "rule __foo_bar___rule\n" | |
293 " command = C$:/python/python.exe gyp-win-tool action-wrapper " | |
294 "environment.x86 __foo_bar___rule.$unique_name.rsp\n" | |
295 " description = ACTION //foo:bar()\n" | |
296 " restat = 1\n" | |
297 " rspfile = __foo_bar___rule.$unique_name.rsp\n" | |
298 " rspfile_content = C$:/python/python.exe ../../foo/script.py -i " | |
299 #if defined(OS_WIN) | |
300 "${in} \"--out=foo$ bar${source_name_part}.o\"\n" | |
301 #else | |
302 "${in} --out=foo\\$ bar${source_name_part}.o\n" | |
303 #endif | |
304 "build obj/foo/bar.inputdeps.stamp: stamp ../../foo/script.py " | |
305 "../../foo/included.txt obj/foo/dep.stamp\n" | |
306 "\n" | |
307 "build input1.out: __foo_bar___rule ../../foo/input1.txt | " | |
308 "obj/foo/bar.inputdeps.stamp\n" | |
309 " unique_name = 0\n" | |
310 " source_name_part = input1\n" | |
311 "build input2.out: __foo_bar___rule ../../foo/input2.txt | " | |
312 "obj/foo/bar.inputdeps.stamp\n" | |
313 " unique_name = 1\n" | |
314 " source_name_part = input2\n" | |
315 "\n" | |
316 "build obj/foo/bar.stamp: " | |
317 "stamp input1.out input2.out || obj/foo/datadep.stamp\n"; | |
318 EXPECT_EQ(expected_win, out.str()); | |
319 } | |
320 } | 246 } |
321 | 247 |
322 TEST(NinjaActionTargetWriter, ForEachWithDepfile) { | 248 TEST(NinjaActionTargetWriter, ForEachWithDepfile) { |
323 TestWithScope setup; | 249 TestWithScope setup; |
324 Err err; | 250 Err err; |
325 | 251 |
326 setup.build_settings()->SetBuildDir(SourceDir("//out/Debug/")); | 252 setup.build_settings()->SetBuildDir(SourceDir("//out/Debug/")); |
327 Target target(setup.settings(), Label(SourceDir("//foo/"), "bar")); | 253 Target target(setup.settings(), Label(SourceDir("//foo/"), "bar")); |
328 target.set_output_type(Target::ACTION_FOREACH); | 254 target.set_output_type(Target::ACTION_FOREACH); |
329 | 255 |
(...skipping 12 matching lines...) Expand all Loading... |
342 | 268 |
343 target.action_values().args() = SubstitutionList::MakeForTest( | 269 target.action_values().args() = SubstitutionList::MakeForTest( |
344 "-i", | 270 "-i", |
345 "{{source}}", | 271 "{{source}}", |
346 "--out=foo bar{{source_name_part}}.o"); | 272 "--out=foo bar{{source_name_part}}.o"); |
347 target.action_values().outputs() = SubstitutionList::MakeForTest( | 273 target.action_values().outputs() = SubstitutionList::MakeForTest( |
348 "//out/Debug/{{source_name_part}}.out"); | 274 "//out/Debug/{{source_name_part}}.out"); |
349 | 275 |
350 target.inputs().push_back(SourceFile("//foo/included.txt")); | 276 target.inputs().push_back(SourceFile("//foo/included.txt")); |
351 | 277 |
352 // Posix. | 278 setup.settings()->set_target_os(Settings::LINUX); |
353 { | 279 setup.build_settings()->set_python_path(base::FilePath(FILE_PATH_LITERAL( |
354 setup.settings()->set_target_os(Settings::LINUX); | 280 "/usr/bin/python"))); |
355 setup.build_settings()->set_python_path(base::FilePath(FILE_PATH_LITERAL( | |
356 "/usr/bin/python"))); | |
357 | 281 |
358 std::ostringstream out; | 282 std::ostringstream out; |
359 NinjaActionTargetWriter writer(&target, out); | 283 NinjaActionTargetWriter writer(&target, out); |
360 writer.Run(); | 284 writer.Run(); |
361 | 285 |
362 const char expected_linux[] = | 286 const char expected_linux[] = |
363 "rule __foo_bar___rule\n" | 287 "rule __foo_bar___rule\n" |
364 " command = /usr/bin/python ../../foo/script.py -i ${in} " | 288 " command = /usr/bin/python ../../foo/script.py -i ${in} " |
365 #if defined(OS_WIN) | 289 #if defined(OS_WIN) |
366 "\"--out=foo$ bar${source_name_part}.o\"\n" | 290 "\"--out=foo$ bar${source_name_part}.o\"\n" |
367 #else | 291 #else |
368 "--out=foo\\$ bar${source_name_part}.o\n" | 292 "--out=foo\\$ bar${source_name_part}.o\n" |
369 #endif | 293 #endif |
370 " description = ACTION //foo:bar()\n" | 294 " description = ACTION //foo:bar()\n" |
371 " restat = 1\n" | 295 " restat = 1\n" |
372 "build obj/foo/bar.inputdeps.stamp: stamp ../../foo/script.py " | 296 "build obj/foo/bar.inputdeps.stamp: stamp ../../foo/script.py " |
373 "../../foo/included.txt\n" | 297 "../../foo/included.txt\n" |
374 "\n" | 298 "\n" |
375 "build input1.out: __foo_bar___rule ../../foo/input1.txt" | 299 "build input1.out: __foo_bar___rule ../../foo/input1.txt" |
376 " | obj/foo/bar.inputdeps.stamp\n" | 300 " | obj/foo/bar.inputdeps.stamp\n" |
377 " source_name_part = input1\n" | 301 " source_name_part = input1\n" |
378 " depfile = gen/input1.d\n" | 302 " depfile = gen/input1.d\n" |
379 "build input2.out: __foo_bar___rule ../../foo/input2.txt" | 303 "build input2.out: __foo_bar___rule ../../foo/input2.txt" |
380 " | obj/foo/bar.inputdeps.stamp\n" | 304 " | obj/foo/bar.inputdeps.stamp\n" |
381 " source_name_part = input2\n" | 305 " source_name_part = input2\n" |
382 " depfile = gen/input2.d\n" | 306 " depfile = gen/input2.d\n" |
383 "\n" | 307 "\n" |
384 "build obj/foo/bar.stamp: stamp input1.out input2.out\n"; | 308 "build obj/foo/bar.stamp: stamp input1.out input2.out\n"; |
385 EXPECT_EQ(expected_linux, out.str()); | 309 EXPECT_EQ(expected_linux, out.str()); |
386 } | 310 } |
387 | 311 |
388 // Windows. | 312 TEST(NinjaActionTargetWriter, ForEachWithResponseFile) { |
389 { | 313 TestWithScope setup; |
390 setup.build_settings()->set_python_path(base::FilePath(FILE_PATH_LITERAL( | 314 Err err; |
391 "C:/python/python.exe"))); | |
392 setup.settings()->set_target_os(Settings::WIN); | |
393 | 315 |
394 std::ostringstream out; | 316 setup.build_settings()->SetBuildDir(SourceDir("//out/Debug/")); |
395 NinjaActionTargetWriter writer(&target, out); | 317 Target target(setup.settings(), Label(SourceDir("//foo/"), "bar")); |
396 writer.Run(); | 318 target.set_output_type(Target::ACTION_FOREACH); |
397 | 319 |
398 const char expected_win[] = | 320 target.sources().push_back(SourceFile("//foo/input1.txt")); |
399 "rule __foo_bar___rule\n" | 321 target.action_values().set_script(SourceFile("//foo/script.py")); |
400 " command = C$:/python/python.exe gyp-win-tool action-wrapper " | 322 |
401 "environment.x86 __foo_bar___rule.$unique_name.rsp\n" | 323 target.SetToolchain(setup.toolchain()); |
402 " description = ACTION //foo:bar()\n" | 324 ASSERT_TRUE(target.OnResolved(&err)); |
403 " restat = 1\n" | 325 |
404 " rspfile = __foo_bar___rule.$unique_name.rsp\n" | 326 // Make sure we get interesting substitutions for both the args and the |
405 " rspfile_content = C$:/python/python.exe ../../foo/script.py -i " | 327 // response file contents. |
406 #if defined(OS_WIN) | 328 target.action_values().args() = SubstitutionList::MakeForTest( |
407 "${in} \"--out=foo$ bar${source_name_part}.o\"\n" | 329 "{{source}}", |
408 #else | 330 "{{source_file_part}}", |
409 "${in} --out=foo\\$ bar${source_name_part}.o\n" | 331 "{{response_file_name}}"); |
410 #endif | 332 target.action_values().rsp_file_contents() = SubstitutionList::MakeForTest( |
411 "build obj/foo/bar.inputdeps.stamp: stamp ../../foo/script.py " | 333 "-j", |
412 "../../foo/included.txt\n" | 334 "{{source_name_part}}"); |
413 "\n" | 335 target.action_values().outputs() = SubstitutionList::MakeForTest( |
414 "build input1.out: __foo_bar___rule ../../foo/input1.txt" | 336 "//out/Debug/{{source_name_part}}.out"); |
415 " | obj/foo/bar.inputdeps.stamp\n" | 337 |
416 " unique_name = 0\n" | 338 setup.settings()->set_target_os(Settings::LINUX); |
417 " source_name_part = input1\n" | 339 setup.build_settings()->set_python_path(base::FilePath(FILE_PATH_LITERAL( |
418 " depfile = gen/input1.d\n" | 340 "/usr/bin/python"))); |
419 "build input2.out: __foo_bar___rule ../../foo/input2.txt" | 341 |
420 " | obj/foo/bar.inputdeps.stamp\n" | 342 std::ostringstream out; |
421 " unique_name = 1\n" | 343 NinjaActionTargetWriter writer(&target, out); |
422 " source_name_part = input2\n" | 344 writer.Run(); |
423 " depfile = gen/input2.d\n" | 345 |
424 "\n" | 346 const char expected_linux[] = |
425 "build obj/foo/bar.stamp: stamp input1.out input2.out\n"; | 347 "rule __foo_bar___rule\n" |
426 EXPECT_EQ(expected_win, out.str()); | 348 // This name is autogenerated from the target rule name. |
427 } | 349 " rspfile = __foo_bar___rule.$unique_name.rsp\n" |
| 350 // These come from rsp_file_contents above. |
| 351 " rspfile_content = -j ${source_name_part}\n" |
| 352 // These come from the args. |
| 353 " command = /usr/bin/python ../../foo/script.py ${in} " |
| 354 "${source_file_part} ${rspfile}\n" |
| 355 " description = ACTION //foo:bar()\n" |
| 356 " restat = 1\n" |
| 357 "build obj/foo/bar.inputdeps.stamp: stamp ../../foo/script.py\n" |
| 358 "\n" |
| 359 "build input1.out: __foo_bar___rule ../../foo/input1.txt" |
| 360 " | obj/foo/bar.inputdeps.stamp\n" |
| 361 // Necessary for the rspfile defined in the rule. |
| 362 " unique_name = 0\n" |
| 363 // Substitution for the args. |
| 364 " source_file_part = input1.txt\n" |
| 365 // Substitution for the rspfile contents. |
| 366 " source_name_part = input1\n" |
| 367 "\n" |
| 368 "build obj/foo/bar.stamp: stamp input1.out\n"; |
| 369 EXPECT_EQ(expected_linux, out.str()); |
428 } | 370 } |
OLD | NEW |