| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 "tools/gn/substitution_writer.h" | 5 #include "tools/gn/substitution_writer.h" |
| 6 | 6 |
| 7 #include "tools/gn/build_settings.h" | 7 #include "tools/gn/build_settings.h" |
| 8 #include "tools/gn/escape.h" | 8 #include "tools/gn/escape.h" |
| 9 #include "tools/gn/filesystem_utils.h" | 9 #include "tools/gn/filesystem_utils.h" |
| 10 #include "tools/gn/output_file.h" | 10 #include "tools/gn/output_file.h" |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 91 source file is in a different directory than the BUILD.gn file. | 91 source file is in a different directory than the BUILD.gn file. |
| 92 "//foo/bar/baz.txt" => "gen/foo/bar" | 92 "//foo/bar/baz.txt" => "gen/foo/bar" |
| 93 | 93 |
| 94 {{source_out_dir}} | 94 {{source_out_dir}} |
| 95 The object file directory (*) corresponding to the source file's path, | 95 The object file directory (*) corresponding to the source file's path, |
| 96 relative to the build directory. this us be different than the target's | 96 relative to the build directory. this us be different than the target's |
| 97 out directory if the source file is in a different directory than the | 97 out directory if the source file is in a different directory than the |
| 98 build.gn file. | 98 build.gn file. |
| 99 "//foo/bar/baz.txt" => "obj/foo/bar" | 99 "//foo/bar/baz.txt" => "obj/foo/bar" |
| 100 | 100 |
| 101 {{source_target_relative}}\n" |
| 102 The path to the source file relative to the target's directory. This will |
| 103 generally be used for replicating the source directory layout in the |
| 104 output directory. This can only be used in actions and it is an error to |
| 105 use in process_file_template where there is no "target". |
| 106 "//foo/bar/baz.txt" => "baz.txt" |
| 107 |
| 101 (*) Note on directories | 108 (*) Note on directories |
| 102 | 109 |
| 103 Paths containing directories (except the source_root_relative_dir) will be | 110 Paths containing directories (except the source_root_relative_dir) will be |
| 104 different depending on what context the expansion is evaluated in. Generally | 111 different depending on what context the expansion is evaluated in. Generally |
| 105 it should "just work" but it means you can't concatenate strings containing | 112 it should "just work" but it means you can't concatenate strings containing |
| 106 these values with reasonable results. | 113 these values with reasonable results. |
| 107 | 114 |
| 108 Details: source expansions can be used in the "outputs" variable, the "args" | 115 Details: source expansions can be used in the "outputs" variable, the "args" |
| 109 variable, and in calls to "process_file_template". The "args" are passed to a | 116 variable, and in calls to "process_file_template". The "args" are passed to a |
| 110 script which is run from the build directory, so these directories will | 117 script which is run from the build directory, so these directories will |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 189 const SubstitutionList& list, | 196 const SubstitutionList& list, |
| 190 std::vector<OutputFile>* output) { | 197 std::vector<OutputFile>* output) { |
| 191 std::vector<SourceFile> output_as_sources; | 198 std::vector<SourceFile> output_as_sources; |
| 192 GetListAsSourceFiles(list, &output_as_sources); | 199 GetListAsSourceFiles(list, &output_as_sources); |
| 193 for (const auto& file : output_as_sources) | 200 for (const auto& file : output_as_sources) |
| 194 output->push_back(OutputFile(settings->build_settings(), file)); | 201 output->push_back(OutputFile(settings->build_settings(), file)); |
| 195 } | 202 } |
| 196 | 203 |
| 197 // static | 204 // static |
| 198 SourceFile SubstitutionWriter::ApplyPatternToSource( | 205 SourceFile SubstitutionWriter::ApplyPatternToSource( |
| 206 const Target* target, |
| 199 const Settings* settings, | 207 const Settings* settings, |
| 200 const SubstitutionPattern& pattern, | 208 const SubstitutionPattern& pattern, |
| 201 const SourceFile& source) { | 209 const SourceFile& source) { |
| 202 std::string result_value = ApplyPatternToSourceAsString( | 210 std::string result_value = ApplyPatternToSourceAsString( |
| 203 settings, pattern, source); | 211 target, settings, pattern, source); |
| 204 CHECK(!result_value.empty() && result_value[0] == '/') | 212 CHECK(!result_value.empty() && result_value[0] == '/') |
| 205 << "The result of the pattern \"" | 213 << "The result of the pattern \"" |
| 206 << pattern.AsString() | 214 << pattern.AsString() |
| 207 << "\" was not a path beginning in \"/\" or \"//\"."; | 215 << "\" was not a path beginning in \"/\" or \"//\"."; |
| 208 return SourceFile(SourceFile::SWAP_IN, &result_value); | 216 return SourceFile(SourceFile::SWAP_IN, &result_value); |
| 209 } | 217 } |
| 210 | 218 |
| 211 // static | 219 // static |
| 212 std::string SubstitutionWriter::ApplyPatternToSourceAsString( | 220 std::string SubstitutionWriter::ApplyPatternToSourceAsString( |
| 221 const Target* target, |
| 213 const Settings* settings, | 222 const Settings* settings, |
| 214 const SubstitutionPattern& pattern, | 223 const SubstitutionPattern& pattern, |
| 215 const SourceFile& source) { | 224 const SourceFile& source) { |
| 216 std::string result_value; | 225 std::string result_value; |
| 217 for (const auto& subrange : pattern.ranges()) { | 226 for (const auto& subrange : pattern.ranges()) { |
| 218 if (subrange.type == SUBSTITUTION_LITERAL) { | 227 if (subrange.type == SUBSTITUTION_LITERAL) { |
| 219 result_value.append(subrange.literal); | 228 result_value.append(subrange.literal); |
| 220 } else { | 229 } else { |
| 221 result_value.append( | 230 result_value.append( |
| 222 GetSourceSubstitution(settings, source, subrange.type, | 231 GetSourceSubstitution(target, settings, source, subrange.type, |
| 223 OUTPUT_ABSOLUTE, SourceDir())); | 232 OUTPUT_ABSOLUTE, SourceDir())); |
| 224 } | 233 } |
| 225 } | 234 } |
| 226 return result_value; | 235 return result_value; |
| 227 } | 236 } |
| 228 | 237 |
| 229 // static | 238 // static |
| 230 OutputFile SubstitutionWriter::ApplyPatternToSourceAsOutputFile( | 239 OutputFile SubstitutionWriter::ApplyPatternToSourceAsOutputFile( |
| 240 const Target* target, |
| 231 const Settings* settings, | 241 const Settings* settings, |
| 232 const SubstitutionPattern& pattern, | 242 const SubstitutionPattern& pattern, |
| 233 const SourceFile& source) { | 243 const SourceFile& source) { |
| 234 SourceFile result_as_source = ApplyPatternToSource(settings, pattern, source); | 244 SourceFile result_as_source = ApplyPatternToSource( |
| 245 target, settings, pattern, source); |
| 235 return OutputFile(settings->build_settings(), result_as_source); | 246 return OutputFile(settings->build_settings(), result_as_source); |
| 236 } | 247 } |
| 237 | 248 |
| 238 // static | 249 // static |
| 239 void SubstitutionWriter::ApplyListToSource( | 250 void SubstitutionWriter::ApplyListToSource( |
| 251 const Target* target, |
| 240 const Settings* settings, | 252 const Settings* settings, |
| 241 const SubstitutionList& list, | 253 const SubstitutionList& list, |
| 242 const SourceFile& source, | 254 const SourceFile& source, |
| 243 std::vector<SourceFile>* output) { | 255 std::vector<SourceFile>* output) { |
| 244 for (const auto& item : list.list()) | 256 for (const auto& item : list.list()) |
| 245 output->push_back(ApplyPatternToSource(settings, item, source)); | 257 output->push_back(ApplyPatternToSource(target, settings, item, source)); |
| 246 } | 258 } |
| 247 | 259 |
| 248 // static | 260 // static |
| 249 void SubstitutionWriter::ApplyListToSourceAsString( | 261 void SubstitutionWriter::ApplyListToSourceAsString( |
| 262 const Target* target, |
| 250 const Settings* settings, | 263 const Settings* settings, |
| 251 const SubstitutionList& list, | 264 const SubstitutionList& list, |
| 252 const SourceFile& source, | 265 const SourceFile& source, |
| 253 std::vector<std::string>* output) { | 266 std::vector<std::string>* output) { |
| 254 for (const auto& item : list.list()) | 267 for (const auto& item : list.list()) |
| 255 output->push_back(ApplyPatternToSourceAsString(settings, item, source)); | 268 output->push_back(ApplyPatternToSourceAsString( |
| 269 target, settings, item, source)); |
| 256 } | 270 } |
| 257 | 271 |
| 258 // static | 272 // static |
| 259 void SubstitutionWriter::ApplyListToSourceAsOutputFile( | 273 void SubstitutionWriter::ApplyListToSourceAsOutputFile( |
| 274 const Target* target, |
| 260 const Settings* settings, | 275 const Settings* settings, |
| 261 const SubstitutionList& list, | 276 const SubstitutionList& list, |
| 262 const SourceFile& source, | 277 const SourceFile& source, |
| 263 std::vector<OutputFile>* output) { | 278 std::vector<OutputFile>* output) { |
| 264 for (const auto& item : list.list()) | 279 for (const auto& item : list.list()) |
| 265 output->push_back(ApplyPatternToSourceAsOutputFile(settings, item, source)); | 280 output->push_back(ApplyPatternToSourceAsOutputFile( |
| 281 target, settings, item, source)); |
| 266 } | 282 } |
| 267 | 283 |
| 268 // static | 284 // static |
| 269 void SubstitutionWriter::ApplyListToSources( | 285 void SubstitutionWriter::ApplyListToSources( |
| 286 const Target* target, |
| 270 const Settings* settings, | 287 const Settings* settings, |
| 271 const SubstitutionList& list, | 288 const SubstitutionList& list, |
| 272 const std::vector<SourceFile>& sources, | 289 const std::vector<SourceFile>& sources, |
| 273 std::vector<SourceFile>* output) { | 290 std::vector<SourceFile>* output) { |
| 274 output->clear(); | 291 output->clear(); |
| 275 for (const auto& source : sources) | 292 for (const auto& source : sources) |
| 276 ApplyListToSource(settings, list, source, output); | 293 ApplyListToSource(target, settings, list, source, output); |
| 277 } | 294 } |
| 278 | 295 |
| 279 // static | 296 // static |
| 280 void SubstitutionWriter::ApplyListToSourcesAsString( | 297 void SubstitutionWriter::ApplyListToSourcesAsString( |
| 298 const Target* target, |
| 281 const Settings* settings, | 299 const Settings* settings, |
| 282 const SubstitutionList& list, | 300 const SubstitutionList& list, |
| 283 const std::vector<SourceFile>& sources, | 301 const std::vector<SourceFile>& sources, |
| 284 std::vector<std::string>* output) { | 302 std::vector<std::string>* output) { |
| 285 output->clear(); | 303 output->clear(); |
| 286 for (const auto& source : sources) | 304 for (const auto& source : sources) |
| 287 ApplyListToSourceAsString(settings, list, source, output); | 305 ApplyListToSourceAsString(target, settings, list, source, output); |
| 288 } | 306 } |
| 289 | 307 |
| 290 // static | 308 // static |
| 291 void SubstitutionWriter::ApplyListToSourcesAsOutputFile( | 309 void SubstitutionWriter::ApplyListToSourcesAsOutputFile( |
| 310 const Target* target, |
| 292 const Settings* settings, | 311 const Settings* settings, |
| 293 const SubstitutionList& list, | 312 const SubstitutionList& list, |
| 294 const std::vector<SourceFile>& sources, | 313 const std::vector<SourceFile>& sources, |
| 295 std::vector<OutputFile>* output) { | 314 std::vector<OutputFile>* output) { |
| 296 output->clear(); | 315 output->clear(); |
| 297 for (const auto& source : sources) | 316 for (const auto& source : sources) |
| 298 ApplyListToSourceAsOutputFile(settings, list, source, output); | 317 ApplyListToSourceAsOutputFile(target, settings, list, source, output); |
| 299 } | 318 } |
| 300 | 319 |
| 301 // static | 320 // static |
| 302 void SubstitutionWriter::WriteNinjaVariablesForSource( | 321 void SubstitutionWriter::WriteNinjaVariablesForSource( |
| 322 const Target* target, |
| 303 const Settings* settings, | 323 const Settings* settings, |
| 304 const SourceFile& source, | 324 const SourceFile& source, |
| 305 const std::vector<SubstitutionType>& types, | 325 const std::vector<SubstitutionType>& types, |
| 306 const EscapeOptions& escape_options, | 326 const EscapeOptions& escape_options, |
| 307 std::ostream& out) { | 327 std::ostream& out) { |
| 308 for (const auto& type : types) { | 328 for (const auto& type : types) { |
| 309 // Don't write SOURCE since that just maps to Ninja's $in variable, which | 329 // Don't write SOURCE since that just maps to Ninja's $in variable, which |
| 310 // is implicit in the rule. RESPONSE_FILE_NAME is written separately | 330 // is implicit in the rule. RESPONSE_FILE_NAME is written separately |
| 311 // only when writing target rules since it can never be used in any | 331 // only when writing target rules since it can never be used in any |
| 312 // other context (like process_file_template). | 332 // other context (like process_file_template). |
| 313 if (type != SUBSTITUTION_SOURCE && type != SUBSTITUTION_RSP_FILE_NAME) { | 333 if (type != SUBSTITUTION_SOURCE && type != SUBSTITUTION_RSP_FILE_NAME) { |
| 314 out << " " << kSubstitutionNinjaNames[type] << " = "; | 334 out << " " << kSubstitutionNinjaNames[type] << " = "; |
| 315 EscapeStringToStream( | 335 EscapeStringToStream( |
| 316 out, | 336 out, |
| 317 GetSourceSubstitution(settings, source, type, OUTPUT_RELATIVE, | 337 GetSourceSubstitution(target, settings, source, type, |
| 338 OUTPUT_RELATIVE, |
| 318 settings->build_settings()->build_dir()), | 339 settings->build_settings()->build_dir()), |
| 319 escape_options); | 340 escape_options); |
| 320 out << std::endl; | 341 out << std::endl; |
| 321 } | 342 } |
| 322 } | 343 } |
| 323 } | 344 } |
| 324 | 345 |
| 325 // static | 346 // static |
| 326 std::string SubstitutionWriter::GetSourceSubstitution( | 347 std::string SubstitutionWriter::GetSourceSubstitution( |
| 348 const Target* target, |
| 327 const Settings* settings, | 349 const Settings* settings, |
| 328 const SourceFile& source, | 350 const SourceFile& source, |
| 329 SubstitutionType type, | 351 SubstitutionType type, |
| 330 OutputStyle output_style, | 352 OutputStyle output_style, |
| 331 const SourceDir& relative_to) { | 353 const SourceDir& relative_to) { |
| 332 std::string to_rebase; | 354 std::string to_rebase; |
| 333 switch (type) { | 355 switch (type) { |
| 334 case SUBSTITUTION_SOURCE: | 356 case SUBSTITUTION_SOURCE: |
| 335 if (source.is_system_absolute()) | 357 if (source.is_system_absolute()) |
| 336 return source.value(); | 358 return source.value(); |
| (...skipping 22 matching lines...) Expand all Loading... |
| 359 case SUBSTITUTION_SOURCE_GEN_DIR: | 381 case SUBSTITUTION_SOURCE_GEN_DIR: |
| 360 to_rebase = DirectoryWithNoLastSlash(GetSubBuildDirAsSourceDir( | 382 to_rebase = DirectoryWithNoLastSlash(GetSubBuildDirAsSourceDir( |
| 361 BuildDirContext(settings), source.GetDir(), BuildDirType::GEN)); | 383 BuildDirContext(settings), source.GetDir(), BuildDirType::GEN)); |
| 362 break; | 384 break; |
| 363 | 385 |
| 364 case SUBSTITUTION_SOURCE_OUT_DIR: | 386 case SUBSTITUTION_SOURCE_OUT_DIR: |
| 365 to_rebase = DirectoryWithNoLastSlash(GetSubBuildDirAsSourceDir( | 387 to_rebase = DirectoryWithNoLastSlash(GetSubBuildDirAsSourceDir( |
| 366 BuildDirContext(settings), source.GetDir(), BuildDirType::OBJ)); | 388 BuildDirContext(settings), source.GetDir(), BuildDirType::OBJ)); |
| 367 break; | 389 break; |
| 368 | 390 |
| 391 case SUBSTITUTION_SOURCE_TARGET_RELATIVE: |
| 392 if (target) { |
| 393 return RebasePath(source.value(), target->label().dir(), |
| 394 settings->build_settings()->root_path_utf8()); |
| 395 } |
| 396 NOTREACHED() |
| 397 << "Cannot use substitution " << kSubstitutionNames[type] |
| 398 << " without target"; |
| 399 return std::string(); |
| 400 |
| 369 default: | 401 default: |
| 370 NOTREACHED() | 402 NOTREACHED() |
| 371 << "Unsupported substitution for this function: " | 403 << "Unsupported substitution for this function: " |
| 372 << kSubstitutionNames[type]; | 404 << kSubstitutionNames[type]; |
| 373 return std::string(); | 405 return std::string(); |
| 374 } | 406 } |
| 375 | 407 |
| 376 // If we get here, the result is a path that should be made relative or | 408 // If we get here, the result is a path that should be made relative or |
| 377 // absolute according to the output_style. Other cases (just file name or | 409 // absolute according to the output_style. Other cases (just file name or |
| 378 // extension extraction) will have been handled via early return above. | 410 // extension extraction) will have been handled via early return above. |
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 495 const Target* target, | 527 const Target* target, |
| 496 const SourceFile& source, | 528 const SourceFile& source, |
| 497 SubstitutionType type) { | 529 SubstitutionType type) { |
| 498 // First try the common tool ones. | 530 // First try the common tool ones. |
| 499 std::string result; | 531 std::string result; |
| 500 if (GetTargetSubstitution(target, type, &result)) | 532 if (GetTargetSubstitution(target, type, &result)) |
| 501 return result; | 533 return result; |
| 502 | 534 |
| 503 // Fall-through to the source ones. | 535 // Fall-through to the source ones. |
| 504 return GetSourceSubstitution( | 536 return GetSourceSubstitution( |
| 505 target->settings(), source, type, OUTPUT_RELATIVE, | 537 target, target->settings(), source, type, OUTPUT_RELATIVE, |
| 506 target->settings()->build_settings()->build_dir()); | 538 target->settings()->build_settings()->build_dir()); |
| 507 } | 539 } |
| 508 | 540 |
| 509 // static | 541 // static |
| 510 OutputFile SubstitutionWriter::ApplyPatternToLinkerAsOutputFile( | 542 OutputFile SubstitutionWriter::ApplyPatternToLinkerAsOutputFile( |
| 511 const Target* target, | 543 const Target* target, |
| 512 const Tool* tool, | 544 const Tool* tool, |
| 513 const SubstitutionPattern& pattern) { | 545 const SubstitutionPattern& pattern) { |
| 514 OutputFile result; | 546 OutputFile result; |
| 515 for (const auto& subrange : pattern.ranges()) { | 547 for (const auto& subrange : pattern.ranges()) { |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 569 return tool->default_output_extension(); | 601 return tool->default_output_extension(); |
| 570 if (target->output_extension().empty()) | 602 if (target->output_extension().empty()) |
| 571 return std::string(); // Explicitly set to no extension. | 603 return std::string(); // Explicitly set to no extension. |
| 572 return std::string(".") + target->output_extension(); | 604 return std::string(".") + target->output_extension(); |
| 573 | 605 |
| 574 default: | 606 default: |
| 575 NOTREACHED(); | 607 NOTREACHED(); |
| 576 return std::string(); | 608 return std::string(); |
| 577 } | 609 } |
| 578 } | 610 } |
| OLD | NEW |