Index: tools/gn/target_generator.cc |
diff --git a/tools/gn/target_generator.cc b/tools/gn/target_generator.cc |
index 12d09fca1527092d16ff2b249a47e72ce739fe14..182bf30b6894a4cc2dd173b153d4f20fdcfc5ade 100644 |
--- a/tools/gn/target_generator.cc |
+++ b/tools/gn/target_generator.cc |
@@ -222,20 +222,53 @@ void TargetGenerator::FillOutputs() { |
if (!value) |
return; |
- std::vector<std::string>& outputs = target_->action_values().outputs(); |
- if (!ExtractListOfStringValues(*value, &outputs, err_)) |
+ SubstitutionList& outputs = target_->action_values().outputs(); |
+ if (!outputs.Parse(*value, err_)) |
return; |
+ // Check the substitutions used are valid for this purpose. |
+ if (!EnsureValidSourcesSubstitutions(outputs.required_types(), |
+ value->origin(), err_)) |
+ return |
+ |
// Validate that outputs are in the output dir. |
- bool allow_templates = target_->output_type() == Target::ACTION_FOREACH || |
- target_->output_type() == Target::COPY_FILES; |
- CHECK(outputs.size() == value->list_value().size()); |
- for (size_t i = 0; i < outputs.size(); i++) { |
+ CHECK(outputs.list().size() == value->list_value().size()); |
+ for (size_t i = 0; i < outputs.list().size(); i++) { |
+ if (!EnsureSubstitutionIsInOutputDir(outputs.list()[i], |
+ value->list_value()[i])) |
+ return; |
+ } |
+} |
+ |
+bool TargetGenerator::EnsureSubstitutionIsInOutputDir( |
+ const SubstitutionPattern& pattern, |
+ const Value& original_value) { |
+ if (pattern.ranges().empty()) { |
+ // Pattern is empty, error out (this prevents weirdness below). |
+ *err_ = Err(original_value, "This has an empty value in it."); |
+ return false; |
+ } |
+ |
+ if (pattern.ranges()[0].type == SUBSTITUTION_LITERAL) { |
+ // If the first thing is a literal, it must start with the output dir. |
if (!EnsureStringIsInOutputDir( |
GetBuildSettings()->build_dir(), |
- outputs[i], value->list_value()[i], allow_templates, err_)) |
- return; |
+ pattern.ranges()[0].literal, original_value, err_)) |
+ return false; |
+ } else { |
+ // Otherwise, the first subrange must be a pattern that expands to |
+ // something in the output directory. |
+ if (!SubstitutionIsInOutputDir(pattern.ranges()[0].type)) { |
+ *err_ = Err(original_value, |
+ "File is not inside output directory.", |
+ "The given file should be in the output directory. Normally you\n" |
+ "would specify\n\"$target_out_dir/foo\" or " |
+ "\"{{source_gen_dir}}/foo\"."); |
+ return false; |
+ } |
} |
+ |
+ return true; |
} |
void TargetGenerator::FillGenericConfigs(const char* var_name, |