diff options
Diffstat (limited to 'Source/cmLocalGenerator.cxx')
-rw-r--r-- | Source/cmLocalGenerator.cxx | 113 |
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); |