summaryrefslogtreecommitdiffstats
path: root/Source/cmLocalGenerator.cxx
diff options
context:
space:
mode:
authorCristian Adam <cristian.adam@gmail.com>2020-05-24 17:10:12 (GMT)
committerBrad King <brad.king@kitware.com>2020-05-27 18:19:03 (GMT)
commit1f791eb1607f0634dfb7aee60e991dfa236b8a27 (patch)
treef52523a0f45fa816b4c27392d2a7d0658d393c19 /Source/cmLocalGenerator.cxx
parent7a40d87036afa10b9ebcefa3ec971072eb456e71 (diff)
downloadCMake-1f791eb1607f0634dfb7aee60e991dfa236b8a27.zip
CMake-1f791eb1607f0634dfb7aee60e991dfa236b8a27.tar.gz
CMake-1f791eb1607f0634dfb7aee60e991dfa236b8a27.tar.bz2
Multi-Ninja: Fix reusable PCHs for MSVC
Fixes: #20721
Diffstat (limited to 'Source/cmLocalGenerator.cxx')
-rw-r--r--Source/cmLocalGenerator.cxx240
1 files changed, 145 insertions, 95 deletions
diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx
index e42eb58..ff05024 100644
--- a/Source/cmLocalGenerator.cxx
+++ b/Source/cmLocalGenerator.cxx
@@ -2569,6 +2569,8 @@ void cmLocalGenerator::AddPchDependencies(cmGeneratorTarget* target)
std::vector<cmSourceFile*> sources;
target->GetSourceFiles(sources, config);
+ const std::string configUpper = cmSystemTools::UpperCase(config);
+
for (const std::string& lang : { "C", "CXX", "OBJC", "OBJCXX" }) {
auto langSources = std::count_if(
sources.begin(), sources.end(), [lang](cmSourceFile* sf) {
@@ -2642,106 +2644,45 @@ void cmLocalGenerator::AddPchDependencies(cmGeneratorTarget* target)
if (this->Makefile->IsOn("CMAKE_PCH_COPY_COMPILE_PDB")) {
- const std::string pdb_prefix =
- this->GetGlobalGenerator()->IsMultiConfig()
- ? cmStrCat(this->GlobalGenerator->GetCMakeCFGIntDir(), "/")
- : "";
-
- const std::string target_compile_pdb_dir = cmStrCat(
- target->GetLocalGenerator()->GetCurrentBinaryDirectory(),
- "/", target->GetName(), ".dir/");
-
- const std::string copy_script =
- cmStrCat(target_compile_pdb_dir, "copy_idb_pdb.cmake");
- cmGeneratedFileStream file(copy_script);
-
- file << "# CMake generated file\n";
- for (auto extension : { ".pdb", ".idb" }) {
- const std::string from_file =
- cmStrCat(reuseTarget->GetLocalGenerator()
- ->GetCurrentBinaryDirectory(),
- "/", *ReuseFrom, ".dir/${PDB_PREFIX}", *ReuseFrom,
- extension);
-
- const std::string to_dir = cmStrCat(
- target->GetLocalGenerator()->GetCurrentBinaryDirectory(),
- "/", target->GetName(), ".dir/${PDB_PREFIX}");
-
- const std::string to_file =
- cmStrCat(to_dir, *ReuseFrom, extension);
-
- std::string dest_file = to_file;
-
- std::string const& prefix =
- target->GetSafeProperty("PREFIX");
- if (!prefix.empty()) {
- dest_file =
- cmStrCat(to_dir, prefix, *ReuseFrom, extension);
- }
-
- file << "if (EXISTS \"" << from_file << "\" AND \""
- << from_file << "\" IS_NEWER_THAN \"" << dest_file
- << "\")\n";
- file << " file(COPY \"" << from_file << "\""
- << " DESTINATION \"" << to_dir << "\")\n";
- if (!prefix.empty()) {
- file << " file(REMOVE \"" << dest_file << "\")\n";
- file << " file(RENAME \"" << to_file << "\" \""
- << dest_file << "\")\n";
- }
- file << "endif()\n";
- }
+ const std::string compilerId =
+ this->Makefile->GetSafeDefinition(
+ cmStrCat("CMAKE_", lang, "_COMPILER_ID"));
- bool stdPipesUTF8 = true;
- cmCustomCommandLines commandLines = cmMakeSingleCommandLine(
- { cmSystemTools::GetCMakeCommand(),
- cmStrCat("-DPDB_PREFIX=", pdb_prefix), "-P",
- copy_script });
-
- const std::string no_main_dependency;
- const std::vector<std::string> no_deps;
- const char* no_message = "";
- const char* no_current_dir = nullptr;
- std::vector<std::string> no_byproducts;
-
- std::vector<std::string> outputs;
- outputs.push_back(cmStrCat(target_compile_pdb_dir, pdb_prefix,
- *ReuseFrom, ".pdb"));
-
- if (this->GetGlobalGenerator()->IsVisualStudio()) {
- this->AddCustomCommandToTarget(
- target->GetName(), outputs, no_deps, commandLines,
- cmCustomCommandType::PRE_BUILD, no_message, no_current_dir,
- true, false, "", "", false,
- cmObjectLibraryCommands::Reject, stdPipesUTF8);
- } else {
- cmImplicitDependsList no_implicit_depends;
- cmSourceFile* copy_rule = this->AddCustomCommandToOutput(
- outputs, no_byproducts, no_deps, no_main_dependency,
- no_implicit_depends, commandLines, no_message,
- no_current_dir, false, true, false, false, "", "",
- stdPipesUTF8);
-
- if (copy_rule) {
- target->AddSource(copy_rule->ResolveFullPath());
- }
- }
+ const std::string compilerVersion =
+ this->Makefile->GetSafeDefinition(
+ cmStrCat("CMAKE_", lang, "_COMPILER_VERSION"));
- target->Target->SetProperty("COMPILE_PDB_OUTPUT_DIRECTORY",
- target_compile_pdb_dir);
+ const std::string langFlags =
+ this->Makefile->GetSafeDefinition(
+ cmStrCat("CMAKE_", lang, "_FLAGS_", configUpper));
+
+ // MSVC 2008 is producing both .pdb and .idb files with /Zi.
+ if ((langFlags.find("/ZI") != std::string::npos ||
+ langFlags.find("-ZI") != std::string::npos) ||
+ (cmSystemTools::VersionCompare(cmSystemTools::OP_LESS,
+ compilerVersion.c_str(),
+ "16.0") &&
+ compilerId == "MSVC")) {
+ CopyPchCompilePdb(config, target, *ReuseFrom, reuseTarget,
+ { ".pdb", ".idb" });
+ } else if ((langFlags.find("/Zi") != std::string::npos ||
+ langFlags.find("-Zi") != std::string::npos)) {
+ CopyPchCompilePdb(config, target, *ReuseFrom, reuseTarget,
+ { ".pdb" });
+ }
}
- std::string pchSourceObj =
- reuseTarget->GetPchFileObject(config, lang, arch);
-
- const std::string configUpper = cmSystemTools::UpperCase(config);
+ if (reuseTarget->GetType() != cmStateEnums::OBJECT_LIBRARY) {
+ std::string pchSourceObj =
+ reuseTarget->GetPchFileObject(config, lang, arch);
- // Link to the pch object file
- target->Target->AppendProperty(
- cmStrCat("LINK_FLAGS_", configUpper),
- cmStrCat(" ",
- this->ConvertToOutputFormat(pchSourceObj, SHELL)),
- true);
+ // Link to the pch object file
+ target->Target->AppendProperty(
+ cmStrCat("LINK_FLAGS_", configUpper),
+ cmStrCat(" ",
+ this->ConvertToOutputFormat(pchSourceObj, SHELL)),
+ true);
+ }
}
} else {
pch_sf->SetProperty("PCH_EXTENSION", pchExtension.c_str());
@@ -2765,6 +2706,115 @@ void cmLocalGenerator::AddPchDependencies(cmGeneratorTarget* target)
}
}
+void cmLocalGenerator::CopyPchCompilePdb(
+ const std::string& config, cmGeneratorTarget* target,
+ const std::string& ReuseFrom, cmGeneratorTarget* reuseTarget,
+ const std::vector<std::string>& extensions)
+{
+ const std::string pdb_prefix =
+ this->GetGlobalGenerator()->IsMultiConfig() ? cmStrCat(config, "/") : "";
+
+ const std::string target_compile_pdb_dir =
+ cmStrCat(target->GetLocalGenerator()->GetCurrentBinaryDirectory(), "/",
+ target->GetName(), ".dir/");
+
+ const std::string copy_script =
+ cmStrCat(target_compile_pdb_dir, "copy_idb_pdb.cmake");
+ cmGeneratedFileStream file(copy_script);
+
+ file << "# CMake generated file\n";
+
+ file << "# The compiler generated pdb file needs to be written to disk\n"
+ << "# by mspdbsrv. The foreach retry loop is needed to make sure\n"
+ << "# the pdb file is ready to be copied.\n\n";
+
+ for (auto const& extension : extensions) {
+ const std::string from_file =
+ cmStrCat(reuseTarget->GetLocalGenerator()->GetCurrentBinaryDirectory(),
+ "/", ReuseFrom, ".dir/${PDB_PREFIX}", ReuseFrom, extension);
+
+ const std::string to_dir =
+ cmStrCat(target->GetLocalGenerator()->GetCurrentBinaryDirectory(), "/",
+ target->GetName(), ".dir/${PDB_PREFIX}");
+
+ const std::string to_file = cmStrCat(to_dir, ReuseFrom, extension);
+
+ std::string dest_file = to_file;
+
+ std::string const& prefix = target->GetSafeProperty("PREFIX");
+ if (!prefix.empty()) {
+ dest_file = cmStrCat(to_dir, prefix, ReuseFrom, extension);
+ }
+
+ file << "foreach(retry RANGE 1 30)\n";
+ file << " if (EXISTS \"" << from_file << "\" AND \"" << from_file
+ << " \" IS_NEWER_THAN \"" << dest_file << "\")\n";
+ file << " execute_process(COMMAND ${CMAKE_COMMAND} -E copy";
+ file << " \"" << from_file << "\""
+ << " \"" << to_dir << "\" RESULT_VARIABLE result "
+ << " ERROR_QUIET)\n";
+ file << " if (NOT result EQUAL 0)\n"
+ << " execute_process(COMMAND ${CMAKE_COMMAND}"
+ << " -E sleep 1)\n"
+ << " else()\n";
+ if (!prefix.empty()) {
+ file << " file(REMOVE \"" << dest_file << "\")\n";
+ file << " file(RENAME \"" << to_file << "\" \"" << dest_file << "\")\n";
+ }
+ file << " break()\n"
+ << " endif()\n";
+ file << " else()\n"
+ << " execute_process(COMMAND ${CMAKE_COMMAND}"
+ << " -E sleep 1)\n"
+ << " endif()\n";
+ file << "endforeach()\n";
+ }
+
+ bool stdPipesUTF8 = true;
+
+ auto configGenex = [&](cm::string_view expr) -> std::string {
+ if (this->GetGlobalGenerator()->IsVisualStudio()) {
+ return cmStrCat("$<$<CONFIG:", config, ">:", expr, ">");
+ }
+ return std::string(expr);
+ };
+
+ cmCustomCommandLines commandLines = cmMakeSingleCommandLine(
+ { configGenex(cmSystemTools::GetCMakeCommand()),
+ configGenex(cmStrCat("-DPDB_PREFIX=", pdb_prefix)), configGenex("-P"),
+ configGenex(copy_script) });
+
+ const std::string no_main_dependency;
+ const std::vector<std::string> no_deps;
+ const char* no_message = "";
+ const char* no_current_dir = nullptr;
+ std::vector<std::string> no_byproducts;
+
+ std::vector<std::string> outputs;
+ outputs.push_back(
+ cmStrCat(target_compile_pdb_dir, pdb_prefix, ReuseFrom, ".pdb"));
+
+ if (this->GetGlobalGenerator()->IsVisualStudio()) {
+ this->AddCustomCommandToTarget(
+ target->GetName(), outputs, no_deps, commandLines,
+ cmCustomCommandType::PRE_BUILD, no_message, no_current_dir, true, false,
+ "", "", false, cmObjectLibraryCommands::Reject, stdPipesUTF8);
+ } else {
+ cmImplicitDependsList no_implicit_depends;
+ cmSourceFile* copy_rule = this->AddCustomCommandToOutput(
+ outputs, no_byproducts, no_deps, no_main_dependency, no_implicit_depends,
+ commandLines, no_message, no_current_dir, false, true, false, false, "",
+ "", stdPipesUTF8);
+
+ if (copy_rule) {
+ target->AddSource(copy_rule->ResolveFullPath());
+ }
+ }
+
+ target->Target->SetProperty("COMPILE_PDB_OUTPUT_DIRECTORY",
+ target_compile_pdb_dir);
+}
+
namespace {
inline void RegisterUnitySources(cmGeneratorTarget* target, cmSourceFile* sf,