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

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

Issue 2387763002: Support for source_target_relative expansion in GN (Closed)
Patch Set: Rebased Created 4 years 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
« no previous file with comments | « tools/gn/substitution_writer.h ('k') | tools/gn/substitution_writer_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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 }
OLDNEW
« no previous file with comments | « tools/gn/substitution_writer.h ('k') | tools/gn/substitution_writer_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698