Chromium Code Reviews| 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 b012e42b0088a0106ffaa01ae1d5421dd6a38fef..80ffd95a85e76bc912874b9eb27dfa73f5100fc1 100644 |
| --- a/tools/gn/ninja_binary_target_writer.cc |
| +++ b/tools/gn/ninja_binary_target_writer.cc |
| @@ -270,30 +270,15 @@ void NinjaBinaryTargetWriter::Run() { |
| WriteCompilerVars(used_types); |
| - // The input dependencies will be 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. |
| + // The input dependencies will be an implicit dependency. This will cause |
| + // Ninja to make sure the inputs are up to date before compiling this source; |
| + // changes in the inputs deps will 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. |
| - OutputFile order_only_dep = |
| + // This is to make sure that we force rebuild the source when the inputs |
| + // change. Why cannot we rely on the dependencies computed by the compiler? |
| + // These dependencies only include headers and might miss other resources |
| + // that are used by the input file. |
| + OutputFile input_dep = |
| WriteInputDepsStampAndGetDep(std::vector<const Target*>()); |
| // For GCC builds, the .gch files are not object files, but still need to be |
| @@ -301,7 +286,7 @@ void NinjaBinaryTargetWriter::Run() { |
| // |pch_other_files|. This is to prevent linking against them. |
| std::vector<OutputFile> pch_obj_files; |
| std::vector<OutputFile> pch_other_files; |
| - WritePCHCommands(used_types, order_only_dep, |
| + WritePCHCommands(used_types, input_dep, |
| &pch_obj_files, &pch_other_files); |
| std::vector<OutputFile>* pch_files = !pch_obj_files.empty() ? |
| &pch_obj_files : &pch_other_files; |
| @@ -320,7 +305,7 @@ void NinjaBinaryTargetWriter::Run() { |
| // object file list. |
| std::vector<OutputFile> obj_files; |
| std::vector<SourceFile> other_files; |
| - WriteSources(*pch_files, order_only_dep, &obj_files, &other_files); |
| + WriteSources(*pch_files, input_dep, &obj_files, &other_files); |
| // Link all MSVC pch object files. The vector will be empty on GCC toolchains. |
| obj_files.insert(obj_files.end(), pch_obj_files.begin(), pch_obj_files.end()); |
| @@ -453,7 +438,7 @@ void NinjaBinaryTargetWriter::WriteOneFlag( |
| void NinjaBinaryTargetWriter::WritePCHCommands( |
| const SourceFileTypeSet& used_types, |
| - const OutputFile& order_only_dep, |
| + const OutputFile& input_dep, |
| std::vector<OutputFile>* object_files, |
| std::vector<OutputFile>* other_files) { |
| if (!target_->config_values().has_precompiled_headers()) |
| @@ -466,7 +451,7 @@ void NinjaBinaryTargetWriter::WritePCHCommands( |
| WritePCHCommand(SUBSTITUTION_CFLAGS_C, |
| Toolchain::TYPE_CC, |
| tool_c->precompiled_header_type(), |
| - order_only_dep, object_files, other_files); |
| + input_dep, object_files, other_files); |
| } |
| const Tool* tool_cxx = target_->toolchain()->GetTool(Toolchain::TYPE_CXX); |
| if (tool_cxx && |
| @@ -475,7 +460,7 @@ void NinjaBinaryTargetWriter::WritePCHCommands( |
| WritePCHCommand(SUBSTITUTION_CFLAGS_CC, |
| Toolchain::TYPE_CXX, |
| tool_cxx->precompiled_header_type(), |
| - order_only_dep, object_files, other_files); |
| + input_dep, object_files, other_files); |
| } |
| const Tool* tool_objc = target_->toolchain()->GetTool(Toolchain::TYPE_OBJC); |
| @@ -485,7 +470,7 @@ void NinjaBinaryTargetWriter::WritePCHCommands( |
| WritePCHCommand(SUBSTITUTION_CFLAGS_OBJC, |
| Toolchain::TYPE_OBJC, |
| tool_objc->precompiled_header_type(), |
| - order_only_dep, object_files, other_files); |
| + input_dep, object_files, other_files); |
| } |
| const Tool* tool_objcxx = |
| @@ -496,7 +481,7 @@ void NinjaBinaryTargetWriter::WritePCHCommands( |
| WritePCHCommand(SUBSTITUTION_CFLAGS_OBJCC, |
| Toolchain::TYPE_OBJCXX, |
| tool_objcxx->precompiled_header_type(), |
| - order_only_dep, object_files, other_files); |
| + input_dep, object_files, other_files); |
| } |
| } |
| @@ -504,16 +489,16 @@ void NinjaBinaryTargetWriter::WritePCHCommand( |
| SubstitutionType flag_type, |
| Toolchain::ToolType tool_type, |
| Tool::PrecompiledHeaderType header_type, |
| - const OutputFile& order_only_dep, |
| + const OutputFile& input_dep, |
| std::vector<OutputFile>* object_files, |
| std::vector<OutputFile>* other_files) { |
| switch (header_type) { |
| case Tool::PCH_MSVC: |
| - WriteWindowsPCHCommand(flag_type, tool_type, order_only_dep, |
| + WriteWindowsPCHCommand(flag_type, tool_type, input_dep, |
| object_files); |
| break; |
| case Tool::PCH_GCC: |
| - WriteGCCPCHCommand(flag_type, tool_type, order_only_dep, |
| + WriteGCCPCHCommand(flag_type, tool_type, input_dep, |
| other_files); |
| break; |
| case Tool::PCH_NONE: |
| @@ -525,7 +510,7 @@ void NinjaBinaryTargetWriter::WritePCHCommand( |
| void NinjaBinaryTargetWriter::WriteGCCPCHCommand( |
| SubstitutionType flag_type, |
| Toolchain::ToolType tool_type, |
| - const OutputFile& order_only_dep, |
| + const OutputFile& input_dep, |
| std::vector<OutputFile>* gch_files) { |
| // Compute the pch output file (it will be language-specific). |
| std::vector<OutputFile> outputs; |
| @@ -535,10 +520,14 @@ void NinjaBinaryTargetWriter::WriteGCCPCHCommand( |
| gch_files->insert(gch_files->end(), outputs.begin(), outputs.end()); |
| + std::vector<OutputFile> deps; |
| + if (!input_dep.value().empty()) { |
|
brettw
2016/06/16 19:41:34
No {}, same for the additions below.
Petr Hosek
2016/06/16 23:11:47
Done.
|
| + deps.push_back(input_dep); |
| + } |
| + |
| // Build line to compile the file. |
| WriteCompilerBuildLine(target_->config_values().precompiled_source(), |
| - std::vector<OutputFile>(), order_only_dep, tool_type, |
| - outputs); |
| + deps, tool_type, outputs); |
| // This build line needs a custom language-specific flags value. Rule-specific |
| // variables are just indented underneath the rule line. |
| @@ -573,7 +562,7 @@ void NinjaBinaryTargetWriter::WriteGCCPCHCommand( |
| void NinjaBinaryTargetWriter::WriteWindowsPCHCommand( |
| SubstitutionType flag_type, |
| Toolchain::ToolType tool_type, |
| - const OutputFile& order_only_dep, |
| + const OutputFile& input_dep, |
| std::vector<OutputFile>* object_files) { |
| // Compute the pch output file (it will be language-specific). |
| std::vector<OutputFile> outputs; |
| @@ -583,10 +572,14 @@ void NinjaBinaryTargetWriter::WriteWindowsPCHCommand( |
| object_files->insert(object_files->end(), outputs.begin(), outputs.end()); |
| + std::vector<OutputFile> deps; |
| + if (!input_dep.value().empty()) { |
| + deps.push_back(input_dep); |
| + } |
| + |
| // Build line to compile the file. |
| WriteCompilerBuildLine(target_->config_values().precompiled_source(), |
| - std::vector<OutputFile>(), order_only_dep, tool_type, |
| - outputs); |
| + deps, tool_type, outputs); |
| // This build line needs a custom language-specific flags value. Rule-specific |
| // variables are just indented underneath the rule line. |
| @@ -604,13 +597,14 @@ void NinjaBinaryTargetWriter::WriteWindowsPCHCommand( |
| void NinjaBinaryTargetWriter::WriteSources( |
| const std::vector<OutputFile>& pch_deps, |
| - const OutputFile& order_only_dep, |
| + const OutputFile& input_dep, |
| std::vector<OutputFile>* object_files, |
| std::vector<SourceFile>* other_files) { |
| object_files->reserve(object_files->size() + target_->sources().size()); |
| std::vector<OutputFile> tool_outputs; // Prevent reallocation in loop. |
| std::vector<OutputFile> deps; |
| + |
| for (const auto& source : target_->sources()) { |
| // Clear the vector but maintain the max capacity to prevent reallocations. |
| deps.resize(0); |
| @@ -621,6 +615,10 @@ void NinjaBinaryTargetWriter::WriteSources( |
| continue; // No output for this source. |
| } |
| + if (!input_dep.value().empty()) { |
| + deps.push_back(input_dep); |
| + } |
| + |
| if (tool_type != Toolchain::TYPE_NONE) { |
| // Only include PCH deps that correspond to the tool type, for instance, |
| // do not specify target_name.precompile.cc.obj (a CXX PCH file) as a dep |
| @@ -650,8 +648,7 @@ void NinjaBinaryTargetWriter::WriteSources( |
| } |
| } |
| } |
| - WriteCompilerBuildLine(source, deps, order_only_dep, tool_type, |
| - tool_outputs); |
| + WriteCompilerBuildLine(source, deps, tool_type, tool_outputs); |
| } |
| // It's theoretically possible for a compiler to produce more than one |
| @@ -664,7 +661,6 @@ void NinjaBinaryTargetWriter::WriteSources( |
| void NinjaBinaryTargetWriter::WriteCompilerBuildLine( |
| const SourceFile& source, |
| const std::vector<OutputFile>& extra_deps, |
| - const OutputFile& order_only_dep, |
| Toolchain::ToolType tool_type, |
| const std::vector<OutputFile>& outputs) { |
| out_ << "build"; |
| @@ -681,11 +677,6 @@ void NinjaBinaryTargetWriter::WriteCompilerBuildLine( |
| path_output_.WriteFile(out_, dep); |
| } |
| } |
| - |
| - if (!order_only_dep.value().empty()) { |
| - out_ << " || "; |
| - path_output_.WriteFile(out_, order_only_dep); |
| - } |
| out_ << std::endl; |
| } |
| @@ -713,7 +704,7 @@ void NinjaBinaryTargetWriter::WriteLinkerStuff( |
| path_output_.WriteFiles(out_, extra_object_files); |
| // Dependencies. |
| - std::vector<OutputFile> implicit_deps; |
| + std::vector<OutputFile> input_deps; |
| std::vector<OutputFile> solibs; |
| for (const Target* cur : linkable_deps) { |
| // All linkable deps should have a link output file. |
| @@ -725,7 +716,7 @@ void NinjaBinaryTargetWriter::WriteLinkerStuff( |
| cur->link_output_file().value()) { |
| // This is a shared library with separate link and deps files. Save for |
| // later. |
| - implicit_deps.push_back(cur->dependency_output_file()); |
| + input_deps.push_back(cur->dependency_output_file()); |
| solibs.push_back(cur->link_output_file()); |
| } else { |
| // Normal case, just link to this target. |
| @@ -739,7 +730,7 @@ void NinjaBinaryTargetWriter::WriteLinkerStuff( |
| for (const SourceFile& src_file : other_files) { |
| if (GetSourceFileType(src_file) == SOURCE_DEF) { |
| optional_def_file = &src_file; |
| - implicit_deps.push_back( |
| + input_deps.push_back( |
| OutputFile(settings_->build_settings(), src_file)); |
| break; // Only one def file is allowed. |
| } |
| @@ -750,15 +741,15 @@ void NinjaBinaryTargetWriter::WriteLinkerStuff( |
| const OrderedSet<LibFile>& libs = target_->all_libs(); |
| for (size_t i = 0; i < libs.size(); i++) { |
| if (libs[i].is_source_file()) { |
| - implicit_deps.push_back( |
| + input_deps.push_back( |
| OutputFile(settings_->build_settings(), libs[i].source_file())); |
| } |
| } |
| // Append implicit dependencies collected above. |
| - if (!implicit_deps.empty()) { |
| + if (!input_deps.empty()) { |
| out_ << " |"; |
| - path_output_.WriteFiles(out_, implicit_deps); |
| + path_output_.WriteFiles(out_, input_deps); |
| } |
| // Append data dependencies as order-only dependencies. |