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