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 |