| Index: tools/gn/ninja_build_writer.cc
|
| diff --git a/tools/gn/ninja_build_writer.cc b/tools/gn/ninja_build_writer.cc
|
| index 50638fbb7876819438dea2b6dbe659779da72731..07d42e13620eb60a6536f1fdd11aff48a5cd1953 100644
|
| --- a/tools/gn/ninja_build_writer.cc
|
| +++ b/tools/gn/ninja_build_writer.cc
|
| @@ -85,6 +85,27 @@ OutputFile GetTargetOutputFile(const Target* target) {
|
| return result;
|
| }
|
|
|
| +bool HasOutputIdenticalToLabel(const Target* target,
|
| + const std::string& short_name) {
|
| + if (target->output_type() != Target::ACTION &&
|
| + target->output_type() != Target::ACTION_FOREACH)
|
| + return false;
|
| +
|
| + // Rather than convert all outputs to be relative to the build directory
|
| + // and then compare to the short name, convert the short name to look like a
|
| + // file in the output directory since this is only one conversion.
|
| + SourceFile short_name_as_source_file(
|
| + target->settings()->build_settings()->build_dir().value() + short_name);
|
| +
|
| + std::vector<SourceFile> outputs_as_source;
|
| + target->action_values().GetOutputsAsSourceFiles(target, &outputs_as_source);
|
| + for (const SourceFile& output_as_source : outputs_as_source) {
|
| + if (output_as_source == short_name_as_source_file)
|
| + return true;
|
| + }
|
| + return false;
|
| +}
|
| +
|
| // Given an output that appears more than once, generates an error message
|
| // that describes the problem and which targets generate it.
|
| Err GetDuplicateOutputError(const std::vector<const Target*>& all_targets,
|
| @@ -294,7 +315,24 @@ bool NinjaBuildWriter::WritePhonyAndAllRules(Err* err) {
|
| if (small_name_count[label.name()] == 1 ||
|
| (target->output_type() == Target::EXECUTABLE &&
|
| exe_count[label.name()] == 1)) {
|
| - WritePhonyRule(target, target_file, label.name(), &written_rules);
|
| + // It's reasonable to generate output files in the root build directory
|
| + // with the same name as the target. Don't generate phony rules for
|
| + // these cases.
|
| + //
|
| + // All of this does not do the general checking of all target's outputs
|
| + // which may theoretically collide. But it's not very reasonable for
|
| + // a script target named "foo" to generate a file named "bar" with no
|
| + // extension in the root build directory while another target is named
|
| + // "bar". If this does occur, the user is likely to be confused when
|
| + // building "bar" that is builds foo anyway, so you probably just
|
| + // shouldn't do that.
|
| + //
|
| + // We should fix this however, and build up all generated script outputs
|
| + // and check everything against that. There are other edge cases that the
|
| + // current phony rule generator doesn't check. We may need to make a big
|
| + // set of every possible generated file in the build for this purpose.
|
| + if (!HasOutputIdenticalToLabel(target, label.name()))
|
| + WritePhonyRule(target, target_file, label.name(), &written_rules);
|
| }
|
|
|
| if (!all_rules.empty())
|
|
|