| 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 |