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