This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "CMake".
The branch, master has been updated via 01cce69870ec7efbb8138f5345aa7ffed8b7ac12 (commit) via a981a9a7451bbabdc5048f982dce4b3553fe9711 (commit) via c9c1eb99fe011546b5d9390c7fbbeebfda491c65 (commit) via 729d997f1073c7a177da5b46b073a08b95adfa74 (commit) from 45b7d5284e11cb34885b756bee8dedeb94fc16cb (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=01cce69870ec7efbb8138f5345aa7ffed8b7ac12 commit 01cce69870ec7efbb8138f5345aa7ffed8b7ac12 Merge: a981a9a c9c1eb9 Author: Kyle Edwards <kyle.edwa...@kitware.com> AuthorDate: Wed Sep 18 15:35:13 2019 +0000 Commit: Kitware Robot <kwro...@kitware.com> CommitDate: Wed Sep 18 11:36:03 2019 -0400 Merge topic 'smart_ptr/cmCPackGeneratorFactory' c9c1eb99fe cmCPackGeneratorFactory: rule of zero Acked-by: Kitware Robot <kwro...@kitware.com> Merge-request: !3826 https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=a981a9a7451bbabdc5048f982dce4b3553fe9711 commit a981a9a7451bbabdc5048f982dce4b3553fe9711 Merge: 45b7d52 729d997 Author: Brad King <brad.k...@kitware.com> AuthorDate: Wed Sep 18 15:33:23 2019 +0000 Commit: Kitware Robot <kwro...@kitware.com> CommitDate: Wed Sep 18 11:34:00 2019 -0400 Merge topic 'shared-pch' 729d997f10 Precompile Headers: Add REUSE_FROM signature Acked-by: Kitware Robot <kwro...@kitware.com> Acked-by: Rickard Englund <rick...@r-englund.com> Acked-by: Viktor Kirilov <vik.kiri...@gmail.com> Merge-request: !3762 https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=c9c1eb99fe011546b5d9390c7fbbeebfda491c65 commit c9c1eb99fe011546b5d9390c7fbbeebfda491c65 Author: Tushar Maheshwari <tushar27...@gmail.com> AuthorDate: Sat Sep 7 14:15:08 2019 +0530 Commit: Kyle Edwards <kyle.edwa...@kitware.com> CommitDate: Tue Sep 17 13:05:26 2019 -0400 cmCPackGeneratorFactory: rule of zero diff --git a/Source/CPack/cmCPackGeneratorFactory.cxx b/Source/CPack/cmCPackGeneratorFactory.cxx index a564eb1..79e344b 100644 --- a/Source/CPack/cmCPackGeneratorFactory.cxx +++ b/Source/CPack/cmCPackGeneratorFactory.cxx @@ -6,7 +6,6 @@ #include <utility> #include "IFW/cmCPackIFWGenerator.h" -#include "cmAlgorithms.h" #ifdef HAVE_FREEBSD_PKG # include "cmCPackFreeBSDGenerator.h" #endif @@ -138,33 +137,21 @@ cmCPackGeneratorFactory::cmCPackGeneratorFactory() #endif } -cmCPackGeneratorFactory::~cmCPackGeneratorFactory() -{ - cmDeleteAll(this->Generators); -} - -cmCPackGenerator* cmCPackGeneratorFactory::NewGenerator( +std::unique_ptr<cmCPackGenerator> cmCPackGeneratorFactory::NewGenerator( const std::string& name) { - cmCPackGenerator* gen = this->NewGeneratorInternal(name); + auto it = this->GeneratorCreators.find(name); + if (it == this->GeneratorCreators.end()) { + return nullptr; + } + std::unique_ptr<cmCPackGenerator> gen(it->second()); if (!gen) { return nullptr; } - this->Generators.push_back(gen); gen->SetLogger(this->Logger); return gen; } -cmCPackGenerator* cmCPackGeneratorFactory::NewGeneratorInternal( - const std::string& name) -{ - auto it = this->GeneratorCreators.find(name); - if (it == this->GeneratorCreators.end()) { - return nullptr; - } - return (it->second)(); -} - void cmCPackGeneratorFactory::RegisterGenerator( const std::string& name, const char* generatorDescription, CreateGeneratorCall* createGenerator) diff --git a/Source/CPack/cmCPackGeneratorFactory.h b/Source/CPack/cmCPackGeneratorFactory.h index da2eb8d..62b7484 100644 --- a/Source/CPack/cmCPackGeneratorFactory.h +++ b/Source/CPack/cmCPackGeneratorFactory.h @@ -6,8 +6,8 @@ #include "cmConfigure.h" // IWYU pragma: keep #include <map> +#include <memory> #include <string> -#include <vector> class cmCPackGenerator; class cmCPackLog; @@ -20,14 +20,9 @@ class cmCPackGeneratorFactory { public: cmCPackGeneratorFactory(); - ~cmCPackGeneratorFactory(); - - cmCPackGeneratorFactory(const cmCPackGeneratorFactory&) = delete; - cmCPackGeneratorFactory& operator=(const cmCPackGeneratorFactory&) = delete; //! Get the generator - cmCPackGenerator* NewGenerator(const std::string& name); - void DeleteGenerator(cmCPackGenerator* gen); + std::unique_ptr<cmCPackGenerator> NewGenerator(const std::string& name); using CreateGeneratorCall = cmCPackGenerator*(); @@ -44,9 +39,6 @@ public: } private: - cmCPackGenerator* NewGeneratorInternal(const std::string& name); - std::vector<cmCPackGenerator*> Generators; - using t_GeneratorCreatorsMap = std::map<std::string, CreateGeneratorCall*>; t_GeneratorCreatorsMap GeneratorCreators; DescriptionsMap GeneratorDescriptions; diff --git a/Source/CPack/cpack.cxx b/Source/CPack/cpack.cxx index ab44a42..ce41d40 100644 --- a/Source/CPack/cpack.cxx +++ b/Source/CPack/cpack.cxx @@ -25,6 +25,7 @@ #include <cstddef> #include <iostream> #include <map> +#include <memory> #include <sstream> #include <string> #include <utility> @@ -237,7 +238,6 @@ int main(int argc, char const* const* argv) cmCPackGeneratorFactory generators; generators.SetLogger(&log); - cmCPackGenerator* cpackGenerator = nullptr; cmDocumentation doc; doc.addCPackStandardDocSections(); @@ -360,7 +360,8 @@ int main(int argc, char const* const* argv) parsed = 0; } if (parsed) { - cpackGenerator = generators.NewGenerator(gen); + std::unique_ptr<cmCPackGenerator> cpackGenerator = + generators.NewGenerator(gen); if (cpackGenerator) { cpackGenerator->SetTrace(trace); cpackGenerator->SetTraceExpand(traceExpand); https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=729d997f1073c7a177da5b46b073a08b95adfa74 commit 729d997f1073c7a177da5b46b073a08b95adfa74 Author: Cristian Adam <cristian.a...@gmail.com> AuthorDate: Fri Aug 30 16:21:19 2019 +0200 Commit: Cristian Adam <cristian.a...@gmail.com> CommitDate: Tue Sep 17 11:58:38 2019 +0200 Precompile Headers: Add REUSE_FROM signature Add the ability to share precompiled headers artifacts between targets. Fixes: #19659 diff --git a/Help/command/target_precompile_headers.rst b/Help/command/target_precompile_headers.rst index 3e28265..7d36b11 100644 --- a/Help/command/target_precompile_headers.rst +++ b/Help/command/target_precompile_headers.rst @@ -9,9 +9,23 @@ Add a list of header files to precompile. <INTERFACE|PUBLIC|PRIVATE> [header1...] [<INTERFACE|PUBLIC|PRIVATE> [header2...] ...]) + target_precompile_headers(<target> REUSE_FROM <other_target>) + Adds header files to :prop_tgt:`PRECOMPILE_HEADERS` or :prop_tgt:`INTERFACE_PRECOMPILE_HEADERS` target properties. +The second signature will reuse an already precompiled header file artefact +from another target. This is done by setting the +:prop_tgt:`PRECOMPILE_HEADERS_REUSE_FROM` to ``<other_target>`` value. +The ``<other_target>`` will become a dependency of ``<target>``. + +.. note:: + + The second signature will require the same set of compiler options, + compiler flags, compiler definitions for both ``<target>``, and + ``<other_target>``. Compilers (e.g. GCC) will issue a warning if the + precompiled header file cannot be used (``-Winvalid-pch``). + Precompiling header files can speed up compilation by creating a partially processed version of some header files, and then using that version during compilations rather than repeatedly parsing the original headers. diff --git a/Help/manual/cmake-properties.7.rst b/Help/manual/cmake-properties.7.rst index 19afb7d..0928abe 100644 --- a/Help/manual/cmake-properties.7.rst +++ b/Help/manual/cmake-properties.7.rst @@ -298,6 +298,7 @@ Properties on Targets /prop_tgt/PDB_OUTPUT_DIRECTORY /prop_tgt/POSITION_INDEPENDENT_CODE /prop_tgt/PRECOMPILE_HEADERS + /prop_tgt/PRECOMPILE_HEADERS_REUSE_FROM /prop_tgt/PREFIX /prop_tgt/PRIVATE_HEADER /prop_tgt/PROJECT_LABEL diff --git a/Help/prop_tgt/PRECOMPILE_HEADERS_REUSE_FROM.rst b/Help/prop_tgt/PRECOMPILE_HEADERS_REUSE_FROM.rst new file mode 100644 index 0000000..d740303 --- /dev/null +++ b/Help/prop_tgt/PRECOMPILE_HEADERS_REUSE_FROM.rst @@ -0,0 +1,7 @@ +PRECOMPILE_HEADERS_REUSE_FROM +----------------------------- + +Target from which to reuse the precomipled headers build artifact. + +See the second signature of :command:`target_precompile_headers` command +for more detailed information. diff --git a/Modules/Platform/Windows-MSVC.cmake b/Modules/Platform/Windows-MSVC.cmake index 6ddcaa3..34f5d03 100644 --- a/Modules/Platform/Windows-MSVC.cmake +++ b/Modules/Platform/Windows-MSVC.cmake @@ -333,10 +333,17 @@ macro(__windows_compiler_msvc lang) set(CMAKE_LINK_PCH ON) if(MSVC_VERSION GREATER_EQUAL 1910) # VS 2017 or greater - set(CMAKE_PCH_PROLOGUE "#pragma system_header") + if (NOT ${CMAKE_${lang}_COMPILER_ID} STREQUAL "Clang") + set(CMAKE_PCH_PROLOGUE "#pragma system_header") + else() + set(CMAKE_PCH_PROLOGUE "#pragma clang system_header") + endif() + endif() + if (NOT ${CMAKE_${lang}_COMPILER_ID} STREQUAL "Clang") + set(CMAKE_PCH_COPY_COMPILE_PDB ON) endif() - set(CMAKE_${lang}_COMPILE_OPTIONS_USE_PCH /Yu<PCH_HEADER> /FI<PCH_HEADER>) - set(CMAKE_${lang}_COMPILE_OPTIONS_CREATE_PCH /Yc<PCH_HEADER> /FI<PCH_HEADER>) + set(CMAKE_${lang}_COMPILE_OPTIONS_USE_PCH /Yu<PCH_HEADER> /Fp<PCH_FILE> /FI<PCH_HEADER>) + set(CMAKE_${lang}_COMPILE_OPTIONS_CREATE_PCH /Yc<PCH_HEADER> /Fp<PCH_FILE> /FI<PCH_HEADER>) if("x${CMAKE_${lang}_COMPILER_ID}" STREQUAL "xMSVC") set(_CMAKE_${lang}_IPO_SUPPORTED_BY_CMAKE YES) diff --git a/Source/cmCommonTargetGenerator.cxx b/Source/cmCommonTargetGenerator.cxx index 33286ad..19a096b 100644 --- a/Source/cmCommonTargetGenerator.cxx +++ b/Source/cmCommonTargetGenerator.cxx @@ -171,6 +171,7 @@ std::string cmCommonTargetGenerator::ComputeTargetCompilePDB() const if (this->GeneratorTarget->GetType() > cmStateEnums::OBJECT_LIBRARY) { return compilePdbPath; } + compilePdbPath = this->GeneratorTarget->GetCompilePDBPath(this->GetConfigName()); if (compilePdbPath.empty()) { diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx index 2ca5706..3a321c5 100644 --- a/Source/cmGeneratorTarget.cxx +++ b/Source/cmGeneratorTarget.cxx @@ -35,6 +35,7 @@ #include "cmRange.h" #include "cmSourceFile.h" #include "cmSourceFileLocation.h" +#include "cmSourceFileLocationKind.h" #include "cmState.h" #include "cmStringAlgorithms.h" #include "cmSystemTools.h" @@ -3371,57 +3372,67 @@ std::string cmGeneratorTarget::GetPchHeader(const std::string& config, } std::string& filename = inserted.first->second; + const cmGeneratorTarget* generatorTarget = this; + const char* pchReuseFrom = + generatorTarget->GetProperty("PRECOMPILE_HEADERS_REUSE_FROM"); + if (pchReuseFrom) { + generatorTarget = + this->GetGlobalGenerator()->FindGeneratorTarget(pchReuseFrom); + } + if (this->GetGlobalGenerator()->IsMultiConfig()) { - filename = - cmStrCat(this->LocalGenerator->GetCurrentBinaryDirectory(), "/"); + filename = cmStrCat( + generatorTarget->LocalGenerator->GetCurrentBinaryDirectory(), "/"); } else { // For GCC we need to have the header file .h[xx] // next to the .h[xx].gch file - filename = this->ObjectDirectory; + filename = generatorTarget->ObjectDirectory; } - filename = cmStrCat(filename, "CMakeFiles/", this->GetName(), + filename = cmStrCat(filename, "CMakeFiles/", generatorTarget->GetName(), ".dir/cmake_pch", ((language == "C") ? ".h" : ".hxx")); const std::string filename_tmp = cmStrCat(filename, ".tmp"); - { + if (!pchReuseFrom) { auto pchPrologue = this->Makefile->GetDefinition("CMAKE_PCH_PROLOGUE"); auto pchEpilogue = this->Makefile->GetDefinition("CMAKE_PCH_EPILOGUE"); - cmGeneratedFileStream file( - filename_tmp, false, - this->GetGlobalGenerator()->GetMakefileEncoding()); - file << "/* generated by CMake */\n\n"; - if (pchPrologue) { - file << pchPrologue << "\n"; - } - if (this->GetGlobalGenerator()->IsXcode()) { - file << "#ifndef CMAKE_SKIP_PRECOMPILE_HEADERS\n"; - } - if (language == "CXX") { - file << "#ifdef __cplusplus\n"; - } - for (auto const& header_bt : headers) { - if (header_bt.Value.empty()) { - continue; + { + cmGeneratedFileStream file( + filename_tmp, false, + this->GetGlobalGenerator()->GetMakefileEncoding()); + file << "/* generated by CMake */\n\n"; + if (pchPrologue) { + file << pchPrologue << "\n"; } - if (header_bt.Value[0] == '<' || header_bt.Value[0] == '"') { - file << "#include " << header_bt.Value << "\n"; - } else { - file << "#include \"" << header_bt.Value << "\"\n"; + if (this->GetGlobalGenerator()->IsXcode()) { + file << "#ifndef CMAKE_SKIP_PRECOMPILE_HEADERS\n"; + } + if (language == "CXX") { + file << "#ifdef __cplusplus\n"; + } + for (auto const& header_bt : headers) { + if (header_bt.Value.empty()) { + continue; + } + if (header_bt.Value[0] == '<' || header_bt.Value[0] == '\"') { + file << "#include " << header_bt.Value << "\n"; + } else { + file << "#include \"" << header_bt.Value << "\"\n"; + } + } + if (language == "CXX") { + file << "#endif // __cplusplus\n"; + } + if (this->GetGlobalGenerator()->IsXcode()) { + file << "#endif // CMAKE_SKIP_PRECOMPILE_HEADERS\n"; + } + if (pchEpilogue) { + file << pchEpilogue << "\n"; } } - if (language == "CXX") { - file << "#endif // __cplusplus\n"; - } - if (this->GetGlobalGenerator()->IsXcode()) { - file << "#endif // CMAKE_SKIP_PRECOMPILE_HEADERS\n"; - } - if (pchEpilogue) { - file << pchEpilogue << "\n"; - } + cmSystemTools::MoveFileIfDifferent(filename_tmp, filename); } - cmSystemTools::MoveFileIfDifferent(filename_tmp, filename); } return inserted.first->second; } @@ -3440,8 +3451,18 @@ std::string cmGeneratorTarget::GetPchSource(const std::string& config, return std::string(); } std::string& filename = inserted.first->second; - filename = cmStrCat(this->LocalGenerator->GetCurrentBinaryDirectory(), - "/CMakeFiles/", this->GetName(), ".dir/cmake_pch"); + + const cmGeneratorTarget* generatorTarget = this; + const char* pchReuseFrom = + generatorTarget->GetProperty("PRECOMPILE_HEADERS_REUSE_FROM"); + if (pchReuseFrom) { + generatorTarget = + this->GetGlobalGenerator()->FindGeneratorTarget(pchReuseFrom); + } + + filename = + cmStrCat(generatorTarget->LocalGenerator->GetCurrentBinaryDirectory(), + "/CMakeFiles/", generatorTarget->GetName(), ".dir/cmake_pch"); // For GCC the source extension will be tranformed into .h[xx].gch if (!this->Makefile->IsOn("CMAKE_LINK_PCH")) { @@ -3449,12 +3470,40 @@ std::string cmGeneratorTarget::GetPchSource(const std::string& config, } else { filename += ((language == "C") ? ".c" : ".cxx"); } + const std::string filename_tmp = cmStrCat(filename, ".tmp"); - { - cmGeneratedFileStream file(filename_tmp); - file << "/* generated by CMake */\n"; + if (!pchReuseFrom) { + { + cmGeneratedFileStream file(filename_tmp); + file << "/* generated by CMake */\n"; + } + cmSystemTools::MoveFileIfDifferent(filename_tmp, filename); } - cmSystemTools::MoveFileIfDifferent(filename_tmp, filename); + } + return inserted.first->second; +} + +std::string cmGeneratorTarget::GetPchFileObject(const std::string& config, + const std::string& language) +{ + if (language != "C" && language != "CXX") { + return std::string(); + } + const auto inserted = + this->PchObjectFiles.insert(std::make_pair(language + config, "")); + if (inserted.second) { + const std::string pchSource = this->GetPchSource(config, language); + if (pchSource.empty()) { + return std::string(); + } + std::string& filename = inserted.first->second; + + this->AddSource(pchSource, true); + + auto pchSf = this->Makefile->GetOrCreateSource( + pchSource, false, cmSourceFileLocationKind::Known); + + filename = cmStrCat(this->ObjectDirectory, this->GetObjectName(pchSf)); } return inserted.first->second; } diff --git a/Source/cmGeneratorTarget.h b/Source/cmGeneratorTarget.h index 4207d65..6c36c4b 100644 --- a/Source/cmGeneratorTarget.h +++ b/Source/cmGeneratorTarget.h @@ -462,6 +462,8 @@ public: const std::string& language) const; std::string GetPchSource(const std::string& config, const std::string& language) const; + std::string GetPchFileObject(const std::string& config, + const std::string& language); bool IsSystemIncludeDirectory(const std::string& dir, const std::string& config, @@ -880,6 +882,7 @@ private: mutable std::set<std::string> LinkImplicitNullProperties; mutable std::map<std::string, std::string> PchHeaders; mutable std::map<std::string, std::string> PchSources; + mutable std::map<std::string, std::string> PchObjectFiles; void ExpandLinkItems(std::string const& prop, std::string const& value, std::string const& config, 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); diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index 6637e32..e65fb25 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -1085,6 +1085,7 @@ void cmTarget::SetProperty(const std::string& prop, const char* value) MAKE_STATIC_PROP(COMPILE_FEATURES); MAKE_STATIC_PROP(COMPILE_OPTIONS); MAKE_STATIC_PROP(PRECOMPILE_HEADERS); + MAKE_STATIC_PROP(PRECOMPILE_HEADERS_REUSE_FROM); MAKE_STATIC_PROP(CUDA_PTX_COMPILATION); MAKE_STATIC_PROP(EXPORT_NAME); MAKE_STATIC_PROP(IMPORTED_GLOBAL); @@ -1231,6 +1232,41 @@ void cmTarget::SetProperty(const std::string& prop, const char* value) << impl->Name << "\")\n"; impl->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str()); return; + } else if (prop == propPRECOMPILE_HEADERS_REUSE_FROM) { + if (this->GetProperty("PRECOMPILE_HEADERS")) { + std::ostringstream e; + e << "PRECOMPILE_HEADERS property is already set on target (\"" + << impl->Name << "\")\n"; + impl->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str()); + return; + } + auto reusedTarget = + impl->Makefile->GetCMakeInstance()->GetGlobalGenerator()->FindTarget( + value); + if (!reusedTarget) { + const std::string e( + "PRECOMPILE_HEADERS_REUSE_FROM set with non existing target"); + impl->Makefile->IssueMessage(MessageType::FATAL_ERROR, e); + return; + } + + std::string reusedFrom = reusedTarget->GetSafeProperty(prop); + if (reusedFrom.empty()) { + reusedFrom = value; + } + + impl->Properties.SetProperty(prop, reusedFrom.c_str()); + + reusedTarget->SetProperty("COMPILE_PDB_NAME", reusedFrom.c_str()); + reusedTarget->SetProperty("COMPILE_PDB_OUTPUT_DIRECTORY", + cmStrCat(reusedFrom, ".dir/").c_str()); + + for (auto p : { "COMPILE_PDB_NAME", "PRECOMPILE_HEADERS", + "INTERFACE_PRECOMPILE_HEADERS" }) { + this->SetProperty(p, reusedTarget->GetProperty(p)); + } + + this->AddUtility(reusedFrom, impl->Makefile); } else { impl->Properties.SetProperty(prop, value); } @@ -1308,6 +1344,14 @@ void cmTarget::AppendProperty(const std::string& prop, const char* value, impl->LinkDirectoriesBacktraces.push_back(lfbt); } } else if (prop == "PRECOMPILE_HEADERS") { + if (this->GetProperty("PRECOMPILE_HEADERS_REUSE_FROM")) { + std::ostringstream e; + e << "PRECOMPILE_HEADERS_REUSE_FROM property is already set on target " + "(\"" + << impl->Name << "\")\n"; + impl->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str()); + return; + } if (value && *value) { impl->PrecompileHeadersEntries.emplace_back(value); cmListFileBacktrace lfbt = impl->Makefile->GetBacktrace(); diff --git a/Source/cmTargetPrecompileHeadersCommand.cxx b/Source/cmTargetPrecompileHeadersCommand.cxx index 30cf1be..97f1bea 100644 --- a/Source/cmTargetPrecompileHeadersCommand.cxx +++ b/Source/cmTargetPrecompileHeadersCommand.cxx @@ -10,7 +10,7 @@ bool cmTargetPrecompileHeadersCommand::InitialPass( std::vector<std::string> const& args, cmExecutionStatus&) { - return this->HandleArguments(args, "PRECOMPILE_HEADERS"); + return this->HandleArguments(args, "PRECOMPILE_HEADERS", PROCESS_REUSE_FROM); } void cmTargetPrecompileHeadersCommand::HandleMissingTarget( diff --git a/Source/cmTargetPropCommandBase.cxx b/Source/cmTargetPropCommandBase.cxx index 3aa845c..4bc3125 100644 --- a/Source/cmTargetPropCommandBase.cxx +++ b/Source/cmTargetPropCommandBase.cxx @@ -65,6 +65,19 @@ bool cmTargetPropCommandBase::HandleArguments( ++argIndex; } + if ((flags & PROCESS_REUSE_FROM) && args[argIndex] == "REUSE_FROM") { + if (args.size() != 3) { + this->SetError("called with incorrect number of arguments"); + return false; + } + ++argIndex; + + this->Target->SetProperty("PRECOMPILE_HEADERS_REUSE_FROM", + args[argIndex].c_str()); + + ++argIndex; + } + this->Property = prop; while (argIndex < args.size()) { diff --git a/Source/cmTargetPropCommandBase.h b/Source/cmTargetPropCommandBase.h index 943285d..b244417 100644 --- a/Source/cmTargetPropCommandBase.h +++ b/Source/cmTargetPropCommandBase.h @@ -17,9 +17,10 @@ class cmTargetPropCommandBase : public cmCommand public: enum ArgumentFlags { - NO_FLAGS = 0, - PROCESS_BEFORE = 1, - PROCESS_SYSTEM = 2 + NO_FLAGS = 0x0, + PROCESS_BEFORE = 0x1, + PROCESS_SYSTEM = 0x2, + PROCESS_REUSE_FROM = 0x3 }; bool HandleArguments(std::vector<std::string> const& args, diff --git a/Tests/RunCMake/PrecompileHeaders/PchReuseFrom.cmake b/Tests/RunCMake/PrecompileHeaders/PchReuseFrom.cmake new file mode 100644 index 0000000..4502456 --- /dev/null +++ b/Tests/RunCMake/PrecompileHeaders/PchReuseFrom.cmake @@ -0,0 +1,20 @@ +cmake_minimum_required(VERSION 3.15) +project(PchReuseFrom C) + +add_library(empty empty.c) +target_precompile_headers(empty PUBLIC + <stdio.h> + <string.h> +) +target_include_directories(empty PUBLIC include) + +add_library(foo foo.c) +target_include_directories(foo PUBLIC include) +target_precompile_headers(foo REUSE_FROM empty) + +add_executable(foobar foobar.c) +target_link_libraries(foobar foo ) +set_target_properties(foobar PROPERTIES PRECOMPILE_HEADERS_REUSE_FROM foo) + +enable_testing() +add_test(NAME foobar COMMAND foobar) diff --git a/Tests/RunCMake/PrecompileHeaders/PchReuseFromSubdir-build-stderr.txt b/Tests/RunCMake/PrecompileHeaders/PchReuseFromSubdir-build-stderr.txt new file mode 100644 index 0000000..8cdcfd9 --- /dev/null +++ b/Tests/RunCMake/PrecompileHeaders/PchReuseFromSubdir-build-stderr.txt @@ -0,0 +1,2 @@ +^(|Warning #670: precompiled header file [^ +]* was not generated in this directory)$ diff --git a/Tests/RunCMake/PrecompileHeaders/PchReuseFromSubdir.cmake b/Tests/RunCMake/PrecompileHeaders/PchReuseFromSubdir.cmake new file mode 100644 index 0000000..fff74dc --- /dev/null +++ b/Tests/RunCMake/PrecompileHeaders/PchReuseFromSubdir.cmake @@ -0,0 +1,18 @@ +cmake_minimum_required(VERSION 3.15) +project(PchReuseFromSubdir C) + +add_library(empty empty.c) +target_precompile_headers(empty PUBLIC + <stdio.h> + <string.h> +) +target_include_directories(empty PUBLIC include) + +add_library(foo foo.c) +target_include_directories(foo PUBLIC include) +target_precompile_headers(foo REUSE_FROM empty) + +subdirs(subdir) + +enable_testing() +add_test(NAME foobar COMMAND foobar) diff --git a/Tests/RunCMake/PrecompileHeaders/RunCMakeTest.cmake b/Tests/RunCMake/PrecompileHeaders/RunCMakeTest.cmake index fffcc47..bd3b1b8 100644 --- a/Tests/RunCMake/PrecompileHeaders/RunCMakeTest.cmake +++ b/Tests/RunCMake/PrecompileHeaders/RunCMakeTest.cmake @@ -16,3 +16,5 @@ run_cmake(DisabledPch) run_test(PchInterface) run_cmake(PchPrologueEpilogue) run_test(SkipPrecompileHeaders) +run_test(PchReuseFrom) +run_test(PchReuseFromSubdir) diff --git a/Tests/RunCMake/PrecompileHeaders/empty.c b/Tests/RunCMake/PrecompileHeaders/empty.c new file mode 100644 index 0000000..30ae1c4 --- /dev/null +++ b/Tests/RunCMake/PrecompileHeaders/empty.c @@ -0,0 +1,3 @@ +void nothing() +{ +} diff --git a/Tests/RunCMake/PrecompileHeaders/include/foo.h b/Tests/RunCMake/PrecompileHeaders/include/foo.h index 4a49474..fc0ae14 100644 --- a/Tests/RunCMake/PrecompileHeaders/include/foo.h +++ b/Tests/RunCMake/PrecompileHeaders/include/foo.h @@ -1,6 +1,6 @@ #ifndef foo_h #define foo_h -extern int foo(); +int foo(void); #endif diff --git a/Tests/RunCMake/PrecompileHeaders/subdir/CMakeLists.txt b/Tests/RunCMake/PrecompileHeaders/subdir/CMakeLists.txt new file mode 100644 index 0000000..fa926c4 --- /dev/null +++ b/Tests/RunCMake/PrecompileHeaders/subdir/CMakeLists.txt @@ -0,0 +1,3 @@ +add_executable(foobar ../foobar.c) +target_link_libraries(foobar foo ) +set_target_properties(foobar PROPERTIES PRECOMPILE_HEADERS_REUSE_FROM foo) ----------------------------------------------------------------------- Summary of changes: Help/command/target_precompile_headers.rst | 14 +++ Help/manual/cmake-properties.7.rst | 1 + Help/prop_tgt/PRECOMPILE_HEADERS_REUSE_FROM.rst | 7 ++ Modules/Platform/Windows-MSVC.cmake | 13 +- Source/CPack/cmCPackGeneratorFactory.cxx | 25 +--- Source/CPack/cmCPackGeneratorFactory.h | 12 +- Source/CPack/cpack.cxx | 5 +- Source/cmCommonTargetGenerator.cxx | 1 + Source/cmGeneratorTarget.cxx | 131 ++++++++++++++------- Source/cmGeneratorTarget.h | 3 + Source/cmLocalGenerator.cxx | 113 +++++++++++++++++- Source/cmTarget.cxx | 44 +++++++ Source/cmTargetPrecompileHeadersCommand.cxx | 2 +- Source/cmTargetPropCommandBase.cxx | 13 ++ Source/cmTargetPropCommandBase.h | 7 +- .../RunCMake/PrecompileHeaders/PchReuseFrom.cmake | 20 ++++ .../PchReuseFromSubdir-build-stderr.txt | 2 + .../PrecompileHeaders/PchReuseFromSubdir.cmake | 18 +++ .../RunCMake/PrecompileHeaders/RunCMakeTest.cmake | 2 + Tests/RunCMake/PrecompileHeaders/empty.c | 3 + Tests/RunCMake/PrecompileHeaders/include/foo.h | 2 +- .../PrecompileHeaders/subdir/CMakeLists.txt | 3 + 22 files changed, 356 insertions(+), 85 deletions(-) create mode 100644 Help/prop_tgt/PRECOMPILE_HEADERS_REUSE_FROM.rst create mode 100644 Tests/RunCMake/PrecompileHeaders/PchReuseFrom.cmake create mode 100644 Tests/RunCMake/PrecompileHeaders/PchReuseFromSubdir-build-stderr.txt create mode 100644 Tests/RunCMake/PrecompileHeaders/PchReuseFromSubdir.cmake create mode 100644 Tests/RunCMake/PrecompileHeaders/empty.c create mode 100644 Tests/RunCMake/PrecompileHeaders/subdir/CMakeLists.txt hooks/post-receive -- CMake _______________________________________________ Cmake-commits mailing list Cmake-commits@cmake.org https://cmake.org/mailman/listinfo/cmake-commits