| Index: tools/gn/ninja_binary_target_writer.cc
|
| diff --git a/tools/gn/ninja_binary_target_writer.cc b/tools/gn/ninja_binary_target_writer.cc
|
| index b96979d66c3009220572c675d9cc5a9c60243274..4c1a7d7e173e806a757e093f9a0315b158425c30 100644
|
| --- a/tools/gn/ninja_binary_target_writer.cc
|
| +++ b/tools/gn/ninja_binary_target_writer.cc
|
| @@ -127,7 +127,7 @@ void NinjaBinaryTargetWriter::WriteSources(
|
| const Target::FileList& sources = target_->sources();
|
| object_files->reserve(sources.size());
|
|
|
| - std::string implicit_deps =
|
| + OutputFile input_dep =
|
| WriteInputDepsStampAndGetDep(std::vector<const Target*>());
|
|
|
| std::string rule_prefix = GetNinjaRulePrefixForToolchain(settings_);
|
| @@ -145,7 +145,35 @@ void NinjaBinaryTargetWriter::WriteSources(
|
| out_ << ": " << rule_prefix << Toolchain::ToolTypeToName(tool_type);
|
| out_ << " ";
|
| path_output_.WriteFile(out_, sources[i]);
|
| - out_ << implicit_deps << std::endl;
|
| + if (!input_dep.value().empty()) {
|
| + // Write out the input dependencies as an order-only dependency. This
|
| + // will cause Ninja to make sure the inputs are up-to-date before
|
| + // compiling this source, but changes in the inputs deps won't cause
|
| + // the file to be recompiled.
|
| + //
|
| + // This is important to prevent changes in unrelated actions that
|
| + // are upstream of this target from causing everything to be recompiled.
|
| + //
|
| + // Why can we get away with this rather than using implicit deps ("|",
|
| + // which will force rebuilds when the inputs change)? For source code,
|
| + // the computed dependencies of all headers will be computed by the
|
| + // compiler, which will cause source rebuilds if any "real" upstream
|
| + // dependencies change.
|
| + //
|
| + // If a .cc file is generated by an input dependency, Ninja will see
|
| + // the input to the build rule doesn't exist, and that it is an output
|
| + // from a previous step, and build the previous step first. This is a
|
| + // "real" dependency and doesn't need | or || to express.
|
| + //
|
| + // The only case where this rule matters is for the first build where
|
| + // no .d files exist, and Ninja doesn't know what that source file
|
| + // depends on. In this case it's sufficient to ensure that the upstream
|
| + // dependencies are built first. This is exactly what Ninja's order-
|
| + // only dependencies expresses.
|
| + out_ << " || ";
|
| + path_output_.WriteFile(out_, input_dep);
|
| + }
|
| + out_ << std::endl;
|
| }
|
|
|
| // It's theoretically possible for a compiler to produce more than one
|
| @@ -215,6 +243,18 @@ void NinjaBinaryTargetWriter::WriteLinkerStuff(
|
| }
|
|
|
| // Append data dependencies as order-only dependencies.
|
| + //
|
| + // This will include data dependencies and input dependencies (like when
|
| + // this target depends on an action). Having the data dependencies in this
|
| + // list ensures that the data is available at runtime when the user builds
|
| + // this target.
|
| + //
|
| + // The action dependencies are not strictly necessary in this case. They
|
| + // should also have been collected via the input deps stamp that each source
|
| + // file has for an order-only dependency, and since this target depends on
|
| + // the sources, there is already an implicit order-only dependency. However,
|
| + // it's extra work to separate these out and there's no disadvantage to
|
| + // listing them again.
|
| WriteOrderOnlyDependencies(non_linkable_deps);
|
|
|
| // End of the link "build" line.
|
|
|