summaryrefslogtreecommitdiffstats
path: root/Source/cmLocalGenerator.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'Source/cmLocalGenerator.cxx')
-rw-r--r--Source/cmLocalGenerator.cxx113
1 files changed, 108 insertions, 5 deletions
diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx
index 5bbb83c..afcd69f 100644
--- a/Source/cmLocalGenerator.cxx
+++ b/Source/cmLocalGenerator.cxx
@@ -4,7 +4,9 @@
#include "cmAlgorithms.h"
#include "cmComputeLinkInformation.h"
+#include "cmCustomCommand.h"
#include "cmCustomCommandGenerator.h"
+#include "cmCustomCommandLines.h"
#include "cmGeneratedFileStream.h"
#include "cmGeneratorExpression.h"
#include "cmGeneratorExpressionEvaluationFile.h"
@@ -2255,23 +2257,124 @@ void cmLocalGenerator::AddPchDependencies(cmGeneratorTarget* target,
return;
}
+ const char* pchReuseFrom =
+ target->GetProperty("PRECOMPILE_HEADERS_REUSE_FROM");
+
auto pch_sf = this->Makefile->GetOrCreateSource(
pchSource, false, cmSourceFileLocationKind::Known);
std::string pchFile = pchHeader;
if (!this->GetGlobalGenerator()->IsXcode()) {
+ if (!pchReuseFrom) {
+ target->AddSource(pchSource, true);
+ }
+
// Exclude the pch files from linking
if (this->Makefile->IsOn("CMAKE_LINK_PCH")) {
- cmSystemTools::ReplaceString(pchFile, (lang == "C" ? ".h" : ".hxx"),
- pchExtension);
- pch_sf->SetProperty("OBJECT_OUTPUTS", pchFile.c_str());
+
+ auto replaceExtension = [](const std::string& str,
+ const std::string& ext) -> std::string {
+ auto dot_pos = str.rfind('.');
+ std::string result;
+ if (dot_pos != std::string::npos) {
+ result = str.substr(0, dot_pos);
+ }
+ result += ext;
+ return result;
+ };
+
+ if (!pchReuseFrom) {
+ std::string pchSourceObj = target->GetPchFileObject(config, lang);
+
+ pchFile = replaceExtension(pchSourceObj, pchExtension);
+ pch_sf->SetProperty("OBJECT_OUTPUTS", pchFile.c_str());
+ } else {
+ auto reuseTarget =
+ this->GlobalGenerator->FindGeneratorTarget(pchReuseFrom);
+
+ 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(),
+ "/", pchReuseFrom, ".dir/${PDB_PREFIX}", pchReuseFrom,
+ extension);
+
+ const std::string to_dir = cmStrCat(
+ target->GetLocalGenerator()->GetCurrentBinaryDirectory(), "/",
+ target->GetName(), ".dir/${PDB_PREFIX}");
+
+ file << "if (EXISTS \"" << from_file << "\")\n";
+ file << " file(COPY \"" << from_file << "\""
+ << " DESTINATION \"" << to_dir << "\")\n";
+ file << "endif()\n";
+ }
+
+ cmCustomCommandLines commandLines;
+ cmCustomCommandLine currentLine;
+ currentLine.push_back(cmSystemTools::GetCMakeCommand());
+ currentLine.push_back(cmStrCat("-DPDB_PREFIX=", pdb_prefix));
+ currentLine.push_back("-P");
+ currentLine.push_back(copy_script);
+ commandLines.push_back(std::move(currentLine));
+
+ 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,
+ pchReuseFrom, ".pdb"));
+
+ if (this->GetGlobalGenerator()->IsMultiConfig()) {
+ this->Makefile->AddCustomCommandToTarget(
+ target->GetName(), outputs, no_deps, commandLines,
+ cmTarget::PRE_BUILD, no_message, no_current_dir);
+ } else {
+ cmImplicitDependsList no_implicit_depends;
+ cmSourceFile* copy_rule = this->Makefile->AddCustomCommandToOutput(
+ outputs, no_byproducts, no_deps, no_main_dependency,
+ no_implicit_depends, commandLines, no_message, no_current_dir);
+
+ if (copy_rule) {
+ target->AddSource(copy_rule->ResolveFullPath());
+ }
+ }
+
+ target->Target->SetProperty("COMPILE_PDB_OUTPUT_DIRECTORY",
+ target_compile_pdb_dir.c_str());
+ }
+
+ std::string pchSourceObj = reuseTarget->GetPchFileObject(config, lang);
+
+ // Link to the pch object file
+ target->Target->SetProperty(
+ "LINK_FLAGS",
+ this->ConvertToOutputFormat(pchSourceObj, SHELL).c_str());
+
+ pchFile = replaceExtension(pchSourceObj, pchExtension);
+ }
} else {
pchFile += pchExtension;
pch_sf->SetProperty("PCH_EXTENSION", pchExtension.c_str());
}
- target->AddSource(pchSource, true);
-
for (auto& str : { std::ref(useOptionList), std::ref(createOptionList) }) {
cmSystemTools::ReplaceString(str, "<PCH_HEADER>", pchHeader);
cmSystemTools::ReplaceString(str, "<PCH_FILE>", pchFile);