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 971f4d87f439bbb3ff4941a263a0603069dab438..f2aec4a7c30d19af84f0a0c9206f4f9c90ef2bba 100644 |
| --- a/tools/gn/ninja_binary_target_writer.cc |
| +++ b/tools/gn/ninja_binary_target_writer.cc |
| @@ -132,8 +132,8 @@ bool GetOutputFilesForSource(const Target* target, |
| return !outputs->empty(); |
| } |
| -// Returns the language-specific prefix/suffix for precomiled header files. |
| -const char* GetPCHLangForToolType(Toolchain::ToolType type) { |
| +// Returns the language-specific suffix for precompiled header files. |
| +const char* GetPCHSuffixForToolType(Toolchain::ToolType type) { |
| switch (type) { |
| case Toolchain::TYPE_CC: |
| return "c"; |
| @@ -149,11 +149,29 @@ const char* GetPCHLangForToolType(Toolchain::ToolType type) { |
| } |
| } |
| +// Returns the language-specific lang recognized by gcc’s -x flag for |
| +// precompiled header files. |
| +const char* GetPCHLangForToolType(Toolchain::ToolType type) { |
| + switch (type) { |
| + case Toolchain::TYPE_CC: |
| + return "c-header"; |
| + case Toolchain::TYPE_CXX: |
| + return "c++-header"; |
| + case Toolchain::TYPE_OBJC: |
| + return "objective-c-header"; |
| + case Toolchain::TYPE_OBJCXX: |
| + return "objective-c++-header"; |
| + default: |
| + NOTREACHED() << "Not a valid PCH tool type type"; |
| + return ""; |
| + } |
| +} |
| + |
| // Returns the object files for the precompiled header of the given type (flag |
| // type and tool type must match). |
| -void GetWindowsPCHObjectFiles(const Target* target, |
| - Toolchain::ToolType tool_type, |
| - std::vector<OutputFile>* outputs) { |
| +void GetPCHObjectFiles(const Target* target, |
| + Toolchain::ToolType tool_type, |
| + std::vector<OutputFile>* outputs) { |
| outputs->clear(); |
| // Compute the tool. This must use the tool type passed in rather than the |
| @@ -174,7 +192,7 @@ void GetWindowsPCHObjectFiles(const Target* target, |
| // Need to annotate the obj files with the language type. For example: |
| // obj/foo/target_name.precompile.obj -> |
| // obj/foo/target_name.precompile.cc.obj |
| - const char* lang_suffix = GetPCHLangForToolType(tool_type); |
| + const char* lang_suffix = GetPCHSuffixForToolType(tool_type); |
|
brettw
2015/08/24 19:36:05
I'm having a hard time trying to compute the inter
Bons
2015/08/24 19:53:57
defines =
include_dirs =
cflags =
cflags_cc =
targ
|
| std::string& output_value = (*outputs)[0].value(); |
| size_t extension_offset = FindExtensionOffset(output_value); |
| if (extension_offset == std::string::npos) { |
| @@ -207,19 +225,19 @@ void AddSourceSetObjectFiles(const Target* source_set, |
| // Precompiled header object files. |
| if (source_set->config_values().has_precompiled_headers()) { |
| if (used_types.Get(SOURCE_C)) { |
| - GetWindowsPCHObjectFiles(source_set, Toolchain::TYPE_CC, &tool_outputs); |
| + GetPCHObjectFiles(source_set, Toolchain::TYPE_CC, &tool_outputs); |
| obj_files->Append(tool_outputs.begin(), tool_outputs.end()); |
| } |
| if (used_types.Get(SOURCE_CPP)) { |
| - GetWindowsPCHObjectFiles(source_set, Toolchain::TYPE_CXX, &tool_outputs); |
| + GetPCHObjectFiles(source_set, Toolchain::TYPE_CXX, &tool_outputs); |
| obj_files->Append(tool_outputs.begin(), tool_outputs.end()); |
| } |
| if (used_types.Get(SOURCE_M)) { |
| - GetWindowsPCHObjectFiles(source_set, Toolchain::TYPE_OBJC, &tool_outputs); |
| + GetPCHObjectFiles(source_set, Toolchain::TYPE_OBJC, &tool_outputs); |
| obj_files->Append(tool_outputs.begin(), tool_outputs.end()); |
| } |
| if (used_types.Get(SOURCE_MM)) { |
| - GetWindowsPCHObjectFiles(source_set, Toolchain::TYPE_OBJCXX, |
| + GetPCHObjectFiles(source_set, Toolchain::TYPE_OBJCXX, |
| &tool_outputs); |
| obj_files->Append(tool_outputs.begin(), tool_outputs.end()); |
| } |
| @@ -251,10 +269,10 @@ void NinjaBinaryTargetWriter::Run() { |
| // 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 |
| + // 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 |
| + // 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. |
| @@ -346,7 +364,7 @@ void NinjaBinaryTargetWriter::WriteCompilerVars( |
| // Some toolchains pass cflags to the assembler since it's the same command, |
| // and cflags_c might also be sent to the objective C compiler. |
| // |
| - // TODO(brettw) remove the SOURCE_M from the CFLAGS_C writing once the Chrome |
| + // TODO(brettw): remove the SOURCE_M from the CFLAGS_C writing once the Chrome |
| // Mac build is updated not to pass cflags_c to .m files. |
| EscapeOptions opts = GetFlagOptions(); |
| if (used_types.Get(SOURCE_C) || used_types.Get(SOURCE_CPP) || |
| @@ -414,30 +432,66 @@ void NinjaBinaryTargetWriter::WritePrecompiledHeaderCommands( |
| const Tool* tool_c = target_->toolchain()->GetTool(Toolchain::TYPE_CC); |
| if (tool_c && |
| - tool_c->precompiled_header_type() == Tool::PCH_MSVC && |
| + tool_c->precompiled_header_type() != Tool::PCH_NONE && |
| used_types.Get(SOURCE_C)) { |
| - WriteWindowsPCHCommand(SUBSTITUTION_CFLAGS_C, |
| - Toolchain::TYPE_CC, |
| - order_only_dep, object_files); |
| + WritePCHCommand(SUBSTITUTION_CFLAGS_C, |
| + Toolchain::TYPE_CC, |
| + tool_c->precompiled_header_type(), |
| + order_only_dep, object_files); |
| } |
| const Tool* tool_cxx = target_->toolchain()->GetTool(Toolchain::TYPE_CXX); |
| if (tool_cxx && |
| - tool_cxx->precompiled_header_type() == Tool::PCH_MSVC && |
| + tool_cxx->precompiled_header_type() != Tool::PCH_NONE && |
| used_types.Get(SOURCE_CPP)) { |
| - WriteWindowsPCHCommand(SUBSTITUTION_CFLAGS_CC, |
| - Toolchain::TYPE_CXX, |
| - order_only_dep, object_files); |
| + WritePCHCommand(SUBSTITUTION_CFLAGS_CC, |
| + Toolchain::TYPE_CXX, |
| + tool_cxx->precompiled_header_type(), |
| + order_only_dep, object_files); |
| + } |
| + |
| + const Tool* tool_objc = target_->toolchain()->GetTool(Toolchain::TYPE_OBJC); |
| + if (tool_objc && |
| + tool_objc->precompiled_header_type() == Tool::PCH_GCC && |
| + used_types.Get(SOURCE_M)) { |
| + WritePCHCommand(SUBSTITUTION_CFLAGS_OBJC, |
| + Toolchain::TYPE_OBJC, |
| + tool_objc->precompiled_header_type(), |
| + order_only_dep, object_files); |
| + } |
| + |
| + const Tool* tool_objcxx = |
| + target_->toolchain()->GetTool(Toolchain::TYPE_OBJCXX); |
| + if (tool_objcxx && |
| + tool_objcxx->precompiled_header_type() == Tool::PCH_GCC && |
| + used_types.Get(SOURCE_MM)) { |
| + WritePCHCommand(SUBSTITUTION_CFLAGS_OBJCC, |
| + Toolchain::TYPE_OBJCXX, |
| + tool_objcxx->precompiled_header_type(), |
| + order_only_dep, object_files); |
| } |
| } |
| -void NinjaBinaryTargetWriter::WriteWindowsPCHCommand( |
| - SubstitutionType flag_type, |
| - Toolchain::ToolType tool_type, |
| - const OutputFile& order_only_dep, |
| - std::vector<OutputFile>* object_files) { |
| +void NinjaBinaryTargetWriter::WritePCHCommand( |
| + SubstitutionType flag_type, |
| + Toolchain::ToolType tool_type, |
| + Tool::PrecompiledHeaderType header_type, |
| + const OutputFile& order_only_dep, |
| + std::vector<OutputFile>* object_files) { |
| + // With the GCC toolset, ensure the precompiled source and precompiled header |
| + // are the same target. |
| + if (header_type == Tool::PCH_GCC) { |
| + SourceFile source = target_->config_values().precompiled_source(); |
| + std::string header_str = target_->config_values().precompiled_header(); |
| + header_str.insert(0, "//"); |
| + SourceFile header = SourceFile(SourceFile::SWAP_IN, &header_str); |
| + if (source != header) { |
| + NOTREACHED() << "PCH source file must equal header for GCC toolchain"; |
| + } |
| + } |
| + |
| // Compute the object file (it will be language-specific). |
| std::vector<OutputFile> outputs; |
| - GetWindowsPCHObjectFiles(target_, tool_type, &outputs); |
| + GetPCHObjectFiles(target_, tool_type, &outputs); |
| if (outputs.empty()) |
| return; |
| object_files->insert(object_files->end(), outputs.begin(), outputs.end()); |
| @@ -447,15 +501,25 @@ void NinjaBinaryTargetWriter::WriteWindowsPCHCommand( |
| std::vector<OutputFile>(), order_only_dep, tool_type, |
| outputs); |
| - // This build line needs a custom language-specific flags value. It needs to |
| - // include the switch to generate the .pch file in addition to the normal |
| - // ones. Rule-specific variables are just indented underneath the rule line, |
| - // and this defines the new one in terms of the old value. |
| + // This build line needs a custom language-specific flags value. Rule-specific |
| + // variables are just indented underneath the rule line, and this defines the |
| + // new one in terms of the old value. |
| out_ << " " << kSubstitutionNinjaNames[flag_type] << " ="; |
| out_ << " ${" << kSubstitutionNinjaNames[flag_type] << "}"; |
| - // Append the command to generate the .pch file. |
| - out_ << " /Yc" << target_->config_values().precompiled_header(); |
| + switch (header_type) { |
| + case Tool::PCH_MSVC: |
| + // Append the command to generate the .pch file. |
| + out_ << " /Yc" << target_->config_values().precompiled_header(); |
| + break; |
| + case Tool::PCH_GCC: |
| + // Append the command to specify the language of the .gch file. |
| + out_ << " -x " << GetPCHLangForToolType(tool_type); |
| + break; |
| + case Tool::PCH_NONE: |
| + NOTREACHED() << "Cannot write a PCH command with no PCH header type"; |
| + break; |
| + } |
| // Write two blank lines to help separate the PCH build lines from the |
| // regular source build lines. |
| @@ -788,11 +852,11 @@ void NinjaBinaryTargetWriter::WriteOrderOnlyDependencies( |
| OutputFile NinjaBinaryTargetWriter::GetWindowsPCHFile( |
| Toolchain::ToolType tool_type) const { |
| // Use "obj/{dir}/{target_name}_{lang}.pch" which ends up |
| - // looking like "obj/chrome/browser/browser.cc.pch" |
| + // looking like "obj/chrome/browser/browser_cc.pch" |
| OutputFile ret = GetTargetOutputDirAsOutputFile(target_); |
| ret.value().append(target_->label().name()); |
| ret.value().push_back('_'); |
| - ret.value().append(GetPCHLangForToolType(tool_type)); |
| + ret.value().append(GetPCHSuffixForToolType(tool_type)); |
| ret.value().append(".pch"); |
| return ret; |