diff options
author | Brad King <brad.king@kitware.com> | 2022-05-03 15:20:13 (GMT) |
---|---|---|
committer | Kitware Robot <kwrobot@kitware.com> | 2022-05-03 15:20:26 (GMT) |
commit | 386496a5442851b7ed5fae2f5c94e4eb04c35ea2 (patch) | |
tree | 4bcc0270ecea92745d7b06cf31c8d4436a9878b9 /Source | |
parent | ef10e61b6b7d3bb264cdbf72e143dbef7be8c736 (diff) | |
parent | c5b56b35c264664e897a2895e2561a5fb8287703 (diff) | |
download | CMake-386496a5442851b7ed5fae2f5c94e4eb04c35ea2.zip CMake-386496a5442851b7ed5fae2f5c94e4eb04c35ea2.tar.gz CMake-386496a5442851b7ed5fae2f5c94e4eb04c35ea2.tar.bz2 |
Merge topic 'cpp-modules-prep'
c5b56b35c2 cmInstallExportGenerator: expose the temporary directory
c107760417 cmNinjaTargetGenerator: support msvc-style deps discovery for scanning
64c15ec018 cmNinjaTargetGenerator: add flags for scanning based on the fileset type
aaa18f15cf cmTarget: add support for querying all file set names
cc4e19710d cmGlobalNinjaGenerator: use an extention based on the modmapfmt
97a68198c9 cmGlobalNinjaGenerator: escape `:` in module names
499009b79c cmTarget: avoid creating export entries if they don't exist
0513a1fe10 cmInstallGenerator: use CMake-private variables in generated code
...
Acked-by: Kitware Robot <kwrobot@kitware.com>
Tested-by: buildbot <buildbot@kitware.com>
Merge-request: !7214
Diffstat (limited to 'Source')
-rw-r--r-- | Source/cmFileSet.cxx | 9 | ||||
-rw-r--r-- | Source/cmGlobalNinjaGenerator.cxx | 9 | ||||
-rw-r--r-- | Source/cmInstallExportGenerator.cxx | 76 | ||||
-rw-r--r-- | Source/cmInstallExportGenerator.h | 4 | ||||
-rw-r--r-- | Source/cmInstallGenerator.cxx | 31 | ||||
-rw-r--r-- | Source/cmNinjaTargetGenerator.cxx | 83 | ||||
-rw-r--r-- | Source/cmTarget.cxx | 18 | ||||
-rw-r--r-- | Source/cmTarget.h | 1 |
8 files changed, 145 insertions, 86 deletions
diff --git a/Source/cmFileSet.cxx b/Source/cmFileSet.cxx index 1d1d29e..d6665a2 100644 --- a/Source/cmFileSet.cxx +++ b/Source/cmFileSet.cxx @@ -45,9 +45,12 @@ cmFileSetVisibility cmFileSetVisibilityFromName(cm::string_view name, if (name == "PRIVATE"_s) { return cmFileSetVisibility::Private; } - mf->IssueMessage( - MessageType::FATAL_ERROR, - cmStrCat("File set visibility \"", name, "\" is not valid.")); + auto msg = cmStrCat("File set visibility \"", name, "\" is not valid."); + if (mf) { + mf->IssueMessage(MessageType::FATAL_ERROR, msg); + } else { + cmSystemTools::Error(msg); + } return cmFileSetVisibility::Private; } diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx index bbc9c54..3726aa4 100644 --- a/Source/cmGlobalNinjaGenerator.cxx +++ b/Source/cmGlobalNinjaGenerator.cxx @@ -2534,6 +2534,11 @@ bool cmGlobalNinjaGenerator::WriteDyndepFile( } } + const char* module_ext = ""; + if (arg_modmapfmt == "gcc") { + module_ext = ".gcm"; + } + // Extend the module map with those provided by this target. // We do this after loading the modules provided by linked targets // in case we have one of the same name that must be preferred. @@ -2550,7 +2555,9 @@ bool cmGlobalNinjaGenerator::WriteDyndepFile( } } else { // Assume the module file path matches the logical module name. - mod = cmStrCat(module_dir, p.LogicalName); + std::string safe_logical_name = p.LogicalName; + cmSystemTools::ReplaceString(safe_logical_name, ":", "-"); + mod = cmStrCat(module_dir, safe_logical_name, module_ext); } mod_files[p.LogicalName] = mod; tm[p.LogicalName] = mod; diff --git a/Source/cmInstallExportGenerator.cxx b/Source/cmInstallExportGenerator.cxx index eb7537d..f1ac656 100644 --- a/Source/cmInstallExportGenerator.cxx +++ b/Source/cmInstallExportGenerator.cxx @@ -2,7 +2,6 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmInstallExportGenerator.h" -#include <algorithm> #include <map> #include <sstream> #include <utility> @@ -54,73 +53,36 @@ bool cmInstallExportGenerator::Compute(cmLocalGenerator* lg) return true; } -void cmInstallExportGenerator::ComputeTempDir() +std::string cmInstallExportGenerator::TempDirCalculate() const { // Choose a temporary directory in which to generate the import // files to be installed. - this->TempDir = cmStrCat(this->LocalGenerator->GetCurrentBinaryDirectory(), - "/CMakeFiles/Export"); + std::string path = cmStrCat( + this->LocalGenerator->GetCurrentBinaryDirectory(), "/CMakeFiles/Export"); if (this->Destination.empty()) { - return; - } - this->TempDir += "/"; - - // Enforce a maximum length. - bool useMD5 = false; -#if defined(_WIN32) || defined(__CYGWIN__) - std::string::size_type const max_total_len = 250; -#else - std::string::size_type const max_total_len = 1000; -#endif - // Will generate files of the form "<temp-dir>/<base>-<config>.<ext>". - std::string::size_type const len = this->TempDir.size() + 1 + - this->FileName.size() + 1 + this->GetMaxConfigLength(); - if (len < max_total_len) { - // Keep the total path length below the limit. - std::string::size_type const max_len = max_total_len - len; - if (this->Destination.size() > max_len) { - useMD5 = true; - } - } else { - useMD5 = true; + return path; } - if (useMD5) { - // Replace the destination path with a hash to keep it short. + #ifndef CMAKE_BOOTSTRAP - this->TempDir += cmSystemTools::ComputeStringMD5(this->Destination); + path += '/'; + // Replace the destination path with a hash to keep it short. + path += cmSystemTools::ComputeStringMD5(this->Destination); #endif - } else { - std::string dest = this->Destination; - // Avoid unix full paths. - if (dest[0] == '/') { - dest[0] = '_'; - } - // Avoid windows full paths by removing colons. - std::replace(dest.begin(), dest.end(), ':', '_'); - // Avoid relative paths that go up the tree. - cmSystemTools::ReplaceString(dest, "../", "__/"); - // Avoid spaces. - std::replace(dest.begin(), dest.end(), ' ', '_'); - this->TempDir += dest; - } + + return path; } -size_t cmInstallExportGenerator::GetMaxConfigLength() const +void cmInstallExportGenerator::ComputeTempDir() { - // Always use at least 8 for "noconfig". - size_t len = 8; - if (this->ConfigurationTypes->empty()) { - if (this->ConfigurationName.size() > 8) { - len = this->ConfigurationName.size(); - } - } else { - for (std::string const& c : *this->ConfigurationTypes) { - if (c.size() > len) { - len = c.size(); - } - } + this->TempDir = this->TempDirCalculate(); +} + +std::string cmInstallExportGenerator::GetTempDir() const +{ + if (this->TempDir.empty()) { + return this->TempDirCalculate(); } - return len; + return this->TempDir; } void cmInstallExportGenerator::GenerateScript(std::ostream& os) diff --git a/Source/cmInstallExportGenerator.h b/Source/cmInstallExportGenerator.h index 54c59f1..dc07d36 100644 --- a/Source/cmInstallExportGenerator.h +++ b/Source/cmInstallExportGenerator.h @@ -4,7 +4,6 @@ #include "cmConfigure.h" // IWYU pragma: keep -#include <cstddef> #include <iosfwd> #include <memory> #include <string> @@ -50,6 +49,7 @@ public: std::string const& GetDestination() const { return this->Destination; } std::string GetDestinationFile() const; std::string GetFileName() const { return this->FileName; } + std::string GetTempDir() const; protected: void GenerateScript(std::ostream& os) override; @@ -57,8 +57,8 @@ protected: void GenerateScriptActions(std::ostream& os, Indent indent) override; void GenerateImportFile(cmExportSet const* exportSet); void GenerateImportFile(const char* config, cmExportSet const* exportSet); + std::string TempDirCalculate() const; void ComputeTempDir(); - size_t GetMaxConfigLength() const; cmExportSet* const ExportSet; std::string const FilePermissions; diff --git a/Source/cmInstallGenerator.cxx b/Source/cmInstallGenerator.cxx index 00eb8c3..87110a9 100644 --- a/Source/cmInstallGenerator.cxx +++ b/Source/cmInstallGenerator.cxx @@ -41,10 +41,10 @@ void cmInstallGenerator::CheckCMP0082(bool& haveSubdirectoryInstall, void cmInstallGenerator::AddInstallRule( std::ostream& os, std::string const& dest, cmInstallType type, std::vector<std::string> const& files, bool optional /* = false */, - const char* permissions_file /* = 0 */, - const char* permissions_dir /* = 0 */, const char* rename /* = 0 */, - const char* literal_args /* = 0 */, Indent indent, - const char* files_var /* = 0 */) + const char* permissions_file /* = nullptr */, + const char* permissions_dir /* = nullptr */, + const char* rename /* = nullptr */, const char* literal_args /* = nullptr */, + Indent indent, const char* files_var /* = nullptr */) { // Use the FILE command to install the file. std::string stype; @@ -91,21 +91,28 @@ void cmInstallGenerator::AddInstallRule( os << "\")\n"; } if (files_var) { - os << indent << "foreach(_f IN LISTS " << files_var << ")\n"; - os << indent.Next() << "get_filename_component(_fn \"${_f}\" NAME)\n"; + os << indent << "foreach(_cmake_abs_file IN LISTS " << files_var + << ")\n"; + os << indent.Next() + << "get_filename_component(_cmake_abs_file_name " + "\"${_cmake_abs_file}\" NAME)\n"; os << indent.Next() << "list(APPEND CMAKE_ABSOLUTE_DESTINATION_FILES \"" - << dest << "/${_fn}\")\n"; + << dest << "/${_cmake_abs_file_name}\")\n"; os << indent << "endforeach()\n"; + os << indent << "unset(_cmake_abs_file_name)\n"; + os << indent << "unset(_cmake_abs_file)\n"; } os << indent << "if(CMAKE_WARN_ON_ABSOLUTE_INSTALL_DESTINATION)\n"; - os << indent.Next() << "message(WARNING \"ABSOLUTE path INSTALL " - << "DESTINATION : ${CMAKE_ABSOLUTE_DESTINATION_FILES}\")\n"; + os << indent.Next() + << "message(WARNING \"ABSOLUTE path INSTALL " + "DESTINATION : ${CMAKE_ABSOLUTE_DESTINATION_FILES}\")\n"; os << indent << "endif()\n"; os << indent << "if(CMAKE_ERROR_ON_ABSOLUTE_INSTALL_DESTINATION)\n"; - os << indent.Next() << "message(FATAL_ERROR \"ABSOLUTE path INSTALL " - << "DESTINATION forbidden (by caller): " - << "${CMAKE_ABSOLUTE_DESTINATION_FILES}\")\n"; + os << indent.Next() + << "message(FATAL_ERROR \"ABSOLUTE path INSTALL " + "DESTINATION forbidden (by caller): " + "${CMAKE_ABSOLUTE_DESTINATION_FILES}\")\n"; os << indent << "endif()\n"; } std::string absDest = ConvertToAbsoluteDestination(dest); diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx index e61b4b6..3fac7f5 100644 --- a/Source/cmNinjaTargetGenerator.cxx +++ b/Source/cmNinjaTargetGenerator.cxx @@ -21,6 +21,7 @@ #include "cmComputeLinkInformation.h" #include "cmCustomCommandGenerator.h" +#include "cmFileSet.h" #include "cmGeneratedFileStream.h" #include "cmGeneratorExpression.h" #include "cmGeneratorTarget.h" @@ -28,6 +29,7 @@ #include "cmLocalGenerator.h" #include "cmLocalNinjaGenerator.h" #include "cmMakefile.h" +#include "cmMessageType.h" #include "cmNinjaNormalTargetGenerator.h" #include "cmNinjaUtilityTargetGenerator.h" #include "cmOutputConverter.h" @@ -39,6 +41,7 @@ #include "cmStateTypes.h" #include "cmStringAlgorithms.h" #include "cmSystemTools.h" +#include "cmTarget.h" #include "cmValue.h" #include "cmake.h" @@ -252,6 +255,55 @@ std::string cmNinjaTargetGenerator::ComputeFlagsForObject( flags, genexInterpreter.Evaluate(pchOptions, COMPILE_OPTIONS)); } + if (this->NeedCxxModuleSupport(language, config)) { + auto const& path = source->GetFullPath(); + auto const* tgt = this->GeneratorTarget->Target; + + std::string file_set_type; + + for (auto const& name : tgt->GetAllFileSetNames()) { + auto const* file_set = tgt->GetFileSet(name); + if (!file_set) { + this->GetMakefile()->IssueMessage( + MessageType::INTERNAL_ERROR, + cmStrCat("Target `", tgt->GetName(), + "` is tracked to have file set `", name, + "`, but it was not found.")); + continue; + } + + auto fileEntries = file_set->CompileFileEntries(); + auto directoryEntries = file_set->CompileDirectoryEntries(); + auto directories = file_set->EvaluateDirectoryEntries( + directoryEntries, this->LocalGenerator, config, this->GeneratorTarget); + + std::map<std::string, std::vector<std::string>> files; + for (auto const& entry : fileEntries) { + file_set->EvaluateFileEntry(directories, files, entry, + this->LocalGenerator, config, + this->GeneratorTarget); + } + + for (auto const& it : files) { + for (auto const& filename : it.second) { + if (filename == path) { + file_set_type = file_set->GetType(); + break; + } + } + } + + if (!file_set_type.empty()) { + std::string source_type_var = cmStrCat( + "CMAKE_EXPERIMENTAL_CXX_MODULE_SOURCE_TYPE_FLAG_", file_set_type); + cmMakefile* mf = this->GetMakefile(); + if (cmValue source_type_flag = mf->GetDefinition(source_type_var)) { + this->LocalGenerator->AppendFlags(flags, *source_type_flag); + } + } + } + } + return flags; } @@ -534,6 +586,7 @@ std::string GetScanCommand(const std::string& cmakeCmd, const std::string& tdi, // not perform explicit preprocessing too. cmNinjaRule GetScanRule( std::string const& ruleName, std::string const& ppFileName, + std::string const& deptype, cmRulePlaceholderExpander::RuleVariables const& vars, const std::string& responseFlag, const std::string& flags, cmRulePlaceholderExpander* const rulePlaceholderExpander, @@ -542,8 +595,13 @@ cmNinjaRule GetScanRule( { cmNinjaRule rule(ruleName); // Scanning always uses a depfile for preprocessor dependencies. - rule.DepType = ""; // no deps= for multiple outputs - rule.DepFile = "$DEP_FILE"; + if (deptype == "msvc"_s) { + rule.DepType = deptype; + rule.DepFile = ""; + } else { + rule.DepType = ""; // no deps= for multiple outputs + rule.DepFile = "$DEP_FILE"; + } cmRulePlaceholderExpander::RuleVariables scanVars; scanVars.CMTargetName = vars.CMTargetName; @@ -647,6 +705,9 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang, cmSystemTools::GetCMakeCommand(), cmLocalGenerator::SHELL); if (needDyndep) { + const auto& scanDepType = this->GetMakefile()->GetSafeDefinition( + cmStrCat("CMAKE_EXPERIMENTAL_", lang, "_SCANDEP_DEPFILE_FORMAT")); + // Rule to scan dependencies of sources that need preprocessing. { std::vector<std::string> scanCommands; @@ -674,10 +735,10 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang, "$DYNDEP_INTERMEDIATE_FILE")); } - auto scanRule = - GetScanRule(scanRuleName, ppFileName, vars, responseFlag, flags, - rulePlaceholderExpander.get(), this->GetLocalGenerator(), - std::move(scanCommands), config); + auto scanRule = GetScanRule( + scanRuleName, ppFileName, scanDepType, vars, responseFlag, flags, + rulePlaceholderExpander.get(), this->GetLocalGenerator(), + std::move(scanCommands), config); scanRule.Comment = cmStrCat("Rule for generating ", lang, " dependencies."); @@ -705,9 +766,10 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang, scanCommands.emplace_back( GetScanCommand(cmakeCmd, tdi, lang, "$in", "$out")); - auto scanRule = GetScanRule( - scanRuleName, "", vars, "", flags, rulePlaceholderExpander.get(), - this->GetLocalGenerator(), std::move(scanCommands), config); + auto scanRule = + GetScanRule(scanRuleName, "", scanDepType, vars, "", flags, + rulePlaceholderExpander.get(), this->GetLocalGenerator(), + std::move(scanCommands), config); // Write the rule for generating dependencies for the given language. scanRule.Comment = cmStrCat("Rule for generating ", lang, @@ -1197,7 +1259,8 @@ cmNinjaBuild GetScanBuildStatement(const std::string& ruleName, scanBuild.Variables["PREPROCESSED_OUTPUT_FILE"] = ppFileName; } - // Scanning always uses a depfile for preprocessor dependencies. + // Scanning always provides a depfile for preprocessor dependencies. This + // variable is unused in `msvc`-deptype scanners. std::string const& depFileName = cmStrCat(scanBuild.Outputs.front(), ".d"); scanBuild.Variables["DEP_FILE"] = lg->ConvertToOutputFormat(depFileName, cmOutputConverter::SHELL); diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index 446964c..feb2ee3 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -1291,7 +1291,12 @@ void cmTarget::AddInstallIncludeDirectories(cmTargetExport const& te, cmStringRange cmTarget::GetInstallIncludeDirectoriesEntries( cmTargetExport const& te) const { - return cmMakeRange(this->impl->InstallIncludeDirectoriesEntries[&te]); + auto i = this->impl->InstallIncludeDirectoriesEntries.find(&te); + if (i == this->impl->InstallIncludeDirectoriesEntries.end()) { + decltype(i->second) empty; + return cmMakeRange(empty); + } + return cmMakeRange(i->second); } cmBTStringRange cmTarget::GetIncludeDirectoriesEntries() const @@ -2540,6 +2545,17 @@ std::string cmTarget::GetInterfaceFileSetsPropertyName(const std::string& type) return ""; } +std::vector<std::string> cmTarget::GetAllFileSetNames() const +{ + std::vector<std::string> result; + + for (auto const& it : this->impl->FileSets) { + result.push_back(it.first); + } + + return result; +} + std::vector<std::string> cmTarget::GetAllInterfaceFileSets() const { std::vector<std::string> result; diff --git a/Source/cmTarget.h b/Source/cmTarget.h index 72497b3..5ed018e 100644 --- a/Source/cmTarget.h +++ b/Source/cmTarget.h @@ -292,6 +292,7 @@ public: const std::string& type, cmFileSetVisibility vis); + std::vector<std::string> GetAllFileSetNames() const; std::vector<std::string> GetAllInterfaceFileSets() const; static std::string GetFileSetsPropertyName(const std::string& type); |