Browse Source

Merge branch 'backport-cxxmodules-export-file-collisions'

Brad King 1 year ago
parent
commit
4cd153afe3

+ 23 - 8
Source/cmExportBuildFileGenerator.cxx

@@ -3,6 +3,7 @@
 #include "cmExportBuildFileGenerator.h"
 
 #include <algorithm>
+#include <cstddef>
 #include <map>
 #include <memory>
 #include <set>
@@ -12,6 +13,7 @@
 #include <cm/string_view>
 #include <cmext/string_view>
 
+#include "cmCryptoHash.h"
 #include "cmExportSet.h"
 #include "cmFileSet.h"
 #include "cmGeneratedFileStream.h"
@@ -156,7 +158,19 @@ bool cmExportBuildFileGenerator::GenerateMainFile(std::ostream& os)
     this->GenerateTargetFileSets(gte, os);
   }
 
-  this->GenerateCxxModuleInformation(os);
+  std::string cxx_modules_name;
+  if (this->ExportSet) {
+    cxx_modules_name = this->ExportSet->GetName();
+  } else {
+    cmCryptoHash hasher(cmCryptoHash::AlgoSHA3_512);
+    constexpr std::size_t HASH_TRUNCATION = 12;
+    for (auto const& target : this->Targets) {
+      hasher.Append(target.Name);
+    }
+    cxx_modules_name = hasher.FinalizeHex().substr(0, HASH_TRUNCATION);
+  }
+
+  this->GenerateCxxModuleInformation(cxx_modules_name, os);
 
   // Generate import file content for each configuration.
   for (std::string const& c : this->Configurations) {
@@ -165,7 +179,7 @@ bool cmExportBuildFileGenerator::GenerateMainFile(std::ostream& os)
 
   // Generate import file content for each configuration.
   for (std::string const& c : this->Configurations) {
-    this->GenerateImportCxxModuleConfigTargetInclusion(c);
+    this->GenerateImportCxxModuleConfigTargetInclusion(cxx_modules_name, c);
   }
 
   this->GenerateMissingTargetsCheckCode(os);
@@ -526,7 +540,7 @@ std::string cmExportBuildFileGenerator::GetCxxModulesDirectory() const
 }
 
 void cmExportBuildFileGenerator::GenerateCxxModuleConfigInformation(
-  std::ostream& os) const
+  std::string const& name, std::ostream& os) const
 {
   const char* opt = "";
   if (this->Configurations.size() > 1) {
@@ -539,13 +553,13 @@ void cmExportBuildFileGenerator::GenerateCxxModuleConfigInformation(
     if (c.empty()) {
       c = "noconfig";
     }
-    os << "include(\"${CMAKE_CURRENT_LIST_DIR}/cxx-modules-" << c << ".cmake\""
-       << opt << ")\n";
+    os << "include(\"${CMAKE_CURRENT_LIST_DIR}/cxx-modules-" << name << '-'
+       << c << ".cmake\"" << opt << ")\n";
   }
 }
 
 bool cmExportBuildFileGenerator::GenerateImportCxxModuleConfigTargetInclusion(
-  std::string config) const
+  std::string const& name, std::string config) const
 {
   auto cxx_modules_dirname = this->GetCxxModulesDirectory();
   if (cxx_modules_dirname.empty()) {
@@ -556,8 +570,9 @@ bool cmExportBuildFileGenerator::GenerateImportCxxModuleConfigTargetInclusion(
     config = "noconfig";
   }
 
-  std::string fileName = cmStrCat(this->FileDir, '/', cxx_modules_dirname,
-                                  "/cxx-modules-", config, ".cmake");
+  std::string fileName =
+    cmStrCat(this->FileDir, '/', cxx_modules_dirname, "/cxx-modules-", name,
+             '-', config, ".cmake");
 
   cmGeneratedFileStream os(fileName, true);
   if (!os) {

+ 4 - 2
Source/cmExportBuildFileGenerator.h

@@ -105,8 +105,10 @@ protected:
   cmExportSet* GetExportSet() const override { return this->ExportSet; }
 
   std::string GetCxxModulesDirectory() const override;
-  void GenerateCxxModuleConfigInformation(std::ostream&) const override;
-  bool GenerateImportCxxModuleConfigTargetInclusion(std::string) const;
+  void GenerateCxxModuleConfigInformation(std::string const&,
+                                          std::ostream&) const override;
+  bool GenerateImportCxxModuleConfigTargetInclusion(std::string const&,
+                                                    std::string) const;
 
   std::pair<std::vector<std::string>, std::string> FindBuildExportInfo(
     cmGlobalGenerator* gg, const std::string& name);

+ 5 - 4
Source/cmExportFileGenerator.cxx

@@ -1587,7 +1587,8 @@ void cmExportFileGenerator::GenerateTargetFileSets(cmGeneratorTarget* gte,
   }
 }
 
-void cmExportFileGenerator::GenerateCxxModuleInformation(std::ostream& os)
+void cmExportFileGenerator::GenerateCxxModuleInformation(
+  std::string const& name, std::ostream& os)
 {
   auto const cxx_module_dirname = this->GetCxxModulesDirectory();
   if (cxx_module_dirname.empty()) {
@@ -1597,19 +1598,19 @@ void cmExportFileGenerator::GenerateCxxModuleInformation(std::ostream& os)
   // Write the include.
   os << "# Include C++ module properties\n"
      << "include(\"${CMAKE_CURRENT_LIST_DIR}/" << cxx_module_dirname
-     << "/cxx-modules.cmake\")\n\n";
+     << "/cxx-modules-" << name << ".cmake\")\n\n";
 
   // Get the path to the file we're going to write.
   std::string path = this->MainImportFile;
   path = cmSystemTools::GetFilenamePath(path);
   auto trampoline_path =
-    cmStrCat(path, '/', cxx_module_dirname, "/cxx-modules.cmake");
+    cmStrCat(path, '/', cxx_module_dirname, "/cxx-modules-", name, ".cmake");
 
   // Include all configuration-specific include files.
   cmGeneratedFileStream ap(trampoline_path, true);
   ap.SetCopyIfDifferent(true);
 
-  this->GenerateCxxModuleConfigInformation(ap);
+  this->GenerateCxxModuleConfigInformation(name, ap);
 }
 
 void cmExportFileGenerator::SetRequiredCMakeVersion(unsigned int major,

+ 3 - 2
Source/cmExportFileGenerator.h

@@ -192,7 +192,7 @@ protected:
   void GenerateTargetFileSets(cmGeneratorTarget* gte, std::ostream& os,
                               cmTargetExport* te = nullptr);
 
-  void GenerateCxxModuleInformation(std::ostream& os);
+  void GenerateCxxModuleInformation(std::string const& name, std::ostream& os);
 
   virtual std::string GetFileSetDirectories(cmGeneratorTarget* gte,
                                             cmFileSet* fileSet,
@@ -253,5 +253,6 @@ private:
                                      const std::string& config) = 0;
 
   virtual std::string GetCxxModulesDirectory() const = 0;
-  virtual void GenerateCxxModuleConfigInformation(std::ostream& os) const = 0;
+  virtual void GenerateCxxModuleConfigInformation(std::string const&,
+                                                  std::ostream& os) const = 0;
 };

+ 9 - 6
Source/cmExportInstallFileGenerator.cxx

@@ -170,10 +170,12 @@ bool cmExportInstallFileGenerator::GenerateMainFile(std::ostream& os)
 
   bool result = true;
 
-  this->GenerateCxxModuleInformation(os);
+  std::string cxx_modules_name = this->IEGen->GetExportSet()->GetName();
+  this->GenerateCxxModuleInformation(cxx_modules_name, os);
   if (requiresConfigFiles) {
     for (std::string const& c : this->Configurations) {
-      if (!this->GenerateImportCxxModuleConfigTargetInclusion(c)) {
+      if (!this->GenerateImportCxxModuleConfigTargetInclusion(cxx_modules_name,
+                                                              c)) {
         result = false;
       }
     }
@@ -724,12 +726,12 @@ std::string cmExportInstallFileGenerator::GetCxxModulesDirectory() const
 }
 
 void cmExportInstallFileGenerator::GenerateCxxModuleConfigInformation(
-  std::ostream& os) const
+  std::string const& name, std::ostream& os) const
 {
   // Now load per-configuration properties for them.
   /* clang-format off */
   os << "# Load information for each installed configuration.\n"
-        "file(GLOB _cmake_cxx_module_includes \"${CMAKE_CURRENT_LIST_DIR}/cxx-modules-*.cmake\")\n"
+        "file(GLOB _cmake_cxx_module_includes \"${CMAKE_CURRENT_LIST_DIR}/cxx-modules-" << name << "-*.cmake\")\n"
         "foreach(_cmake_cxx_module_include IN LISTS _cmake_cxx_module_includes)\n"
         "  include(\"${_cmake_cxx_module_include}\")\n"
         "endforeach()\n"
@@ -739,7 +741,8 @@ void cmExportInstallFileGenerator::GenerateCxxModuleConfigInformation(
 }
 
 bool cmExportInstallFileGenerator::
-  GenerateImportCxxModuleConfigTargetInclusion(std::string const& config)
+  GenerateImportCxxModuleConfigTargetInclusion(std::string const& name,
+                                               std::string const& config)
 {
   auto cxx_modules_dirname = this->GetCxxModulesDirectory();
   if (cxx_modules_dirname.empty()) {
@@ -754,7 +757,7 @@ bool cmExportInstallFileGenerator::
   std::string const dest =
     cmStrCat(this->FileDir, '/', cxx_modules_dirname, '/');
   std::string fileName =
-    cmStrCat(dest, "cxx-modules-", filename_config, ".cmake");
+    cmStrCat(dest, "cxx-modules-", name, '-', filename_config, ".cmake");
 
   cmGeneratedFileStream os(fileName, true);
   if (!os) {

+ 4 - 2
Source/cmExportInstallFileGenerator.h

@@ -119,8 +119,10 @@ protected:
                               cmTargetExport* te) override;
 
   std::string GetCxxModulesDirectory() const override;
-  void GenerateCxxModuleConfigInformation(std::ostream&) const override;
-  bool GenerateImportCxxModuleConfigTargetInclusion(std::string const&);
+  void GenerateCxxModuleConfigInformation(std::string const&,
+                                          std::ostream&) const override;
+  bool GenerateImportCxxModuleConfigTargetInclusion(std::string const&,
+                                                    std::string const&);
 
   cmExportSet* GetExportSet() const override
   {

+ 4 - 1
Source/cmExportTryCompileFileGenerator.h

@@ -56,7 +56,10 @@ protected:
                               cmTargetExport* te) override;
 
   std::string GetCxxModulesDirectory() const override { return {}; }
-  void GenerateCxxModuleConfigInformation(std::ostream&) const override {}
+  void GenerateCxxModuleConfigInformation(std::string const&,
+                                          std::ostream&) const override
+  {
+  }
 
 private:
   std::string FindTargets(const std::string& prop,

+ 3 - 3
Source/cmGeneratorTarget.cxx

@@ -8417,14 +8417,14 @@ bool cmGeneratorTarget::DiscoverSyntheticTargets(cmSyntheticTargetCache& cache,
     }
 
     if (gt->HaveCxx20ModuleSources()) {
-      auto hasher = cmCryptoHash::New("SHA3_512");
+      cmCryptoHash hasher(cmCryptoHash::AlgoSHA3_512);
       constexpr size_t HASH_TRUNCATION = 12;
-      auto dirhash = hasher->HashString(
+      auto dirhash = hasher.HashString(
         gt->GetLocalGenerator()->GetCurrentBinaryDirectory());
       std::string safeName = gt->GetName();
       cmSystemTools::ReplaceString(safeName, ":", "_");
       auto targetIdent =
-        hasher->HashString(cmStrCat("@d_", dirhash, "@u_", usage.GetHash()));
+        hasher.HashString(cmStrCat("@d_", dirhash, "@u_", usage.GetHash()));
       std::string targetName =
         cmStrCat(safeName, "@synth_", targetIdent.substr(0, HASH_TRUNCATION));
 

+ 3 - 4
Source/cmImportedCxxModuleInfo.cxx

@@ -4,7 +4,6 @@
 #include "cmImportedCxxModuleInfo.h"
 
 #include <cstddef>
-#include <memory>
 #include <string>
 #include <utility>
 #include <vector>
@@ -60,13 +59,13 @@ std::string ImportedCxxModuleLookup::BmiNameForSource(std::string const& path)
 
   auto importit = this->ImportedInfo.find(path);
   std::string bmiName;
-  auto hasher = cmCryptoHash::New("SHA3_512");
+  cmCryptoHash hasher(cmCryptoHash::AlgoSHA3_512);
   constexpr size_t HASH_TRUNCATION = 12;
   if (importit != this->ImportedInfo.end()) {
-    auto safename = hasher->HashString(importit->second.Name);
+    auto safename = hasher.HashString(importit->second.Name);
     bmiName = cmStrCat(safename.substr(0, HASH_TRUNCATION), ".bmi");
   } else {
-    auto dirhash = hasher->HashString(path);
+    auto dirhash = hasher.HashString(path);
     bmiName = cmStrCat(dirhash.substr(0, HASH_TRUNCATION), ".bmi");
   }
 

+ 3 - 2
Source/cmInstallExportGenerator.cxx

@@ -160,10 +160,11 @@ void cmInstallExportGenerator::GenerateScriptConfigs(std::ostream& os,
     // Remove old per-configuration export files if the main changes.
     std::string installedDir = cmStrCat(
       "$ENV{DESTDIR}", ConvertToAbsoluteDestination(cxx_module_dest), '/');
-    std::string installedFile = cmStrCat(installedDir, "/cxx-modules.cmake");
+    std::string installedFile = cmStrCat(installedDir, "/cxx-modules-",
+                                         this->ExportSet->GetName(), ".cmake");
     std::string toInstallFile =
       cmStrCat(cmSystemTools::GetFilenamePath(config_file_example),
-               "/cxx-modules.cmake");
+               "/cxx-modules-", this->ExportSet->GetName(), ".cmake");
     os << indent << "if(EXISTS \"" << installedFile << "\")\n";
     Indent indentN = indent.Next();
     Indent indentNN = indentN.Next();

+ 6 - 6
Tests/RunCMake/CXXModules/ExportBuildCxxModules-check.cmake

@@ -1,19 +1,19 @@
 file(READ "${RunCMake_TEST_BINARY_DIR}/lib/cmake/export-modules/export-modules-targets.cmake" export_script)
 
-if (NOT export_script MATCHES [[include\("\${CMAKE_CURRENT_LIST_DIR}/cxx-modules/cxx-modules\.cmake"\)]])
+if (NOT export_script MATCHES [[include\("\${CMAKE_CURRENT_LIST_DIR}/cxx-modules/cxx-modules-exp\.cmake"\)]])
   list(APPEND RunCMake_TEST_FAILED
     "Could not find C++ module property script inclusion")
 endif ()
 
-file(READ "${RunCMake_TEST_BINARY_DIR}/lib/cmake/export-modules/cxx-modules/cxx-modules.cmake" trampoline_script)
+file(READ "${RunCMake_TEST_BINARY_DIR}/lib/cmake/export-modules/cxx-modules/cxx-modules-exp.cmake" trampoline_script)
 
 if (RunCMake_GENERATOR_IS_MULTI_CONFIG)
-  if (NOT trampoline_script MATCHES [[include\("\${CMAKE_CURRENT_LIST_DIR}/cxx-modules-[^.]*\.cmake" OPTIONAL\)]])
+  if (NOT trampoline_script MATCHES [[include\("\${CMAKE_CURRENT_LIST_DIR}/cxx-modules-exp-[^.]*\.cmake" OPTIONAL\)]])
     list(APPEND RunCMake_TEST_FAILED
       "Could not find C++ module property per-config script inclusion(s)")
   endif ()
 else ()
-  if (NOT trampoline_script MATCHES [[include\("\${CMAKE_CURRENT_LIST_DIR}/cxx-modules-[^.]*\.cmake"\)]])
+  if (NOT trampoline_script MATCHES [[include\("\${CMAKE_CURRENT_LIST_DIR}/cxx-modules-exp-[^.]*\.cmake"\)]])
     list(APPEND RunCMake_TEST_FAILED
       "Could not find C++ module property per-config script inclusion(s)")
   endif ()
@@ -21,12 +21,12 @@ endif ()
 
 set(any_exists 0)
 foreach (config IN ITEMS noconfig Debug Release RelWithDebInfo MinSizeRel)
-  if (NOT EXISTS "${RunCMake_TEST_BINARY_DIR}/lib/cmake/export-modules/cxx-modules/cxx-modules-${config}.cmake")
+  if (NOT EXISTS "${RunCMake_TEST_BINARY_DIR}/lib/cmake/export-modules/cxx-modules/cxx-modules-exp-${config}.cmake")
     continue ()
   endif ()
   set(any_exists 1)
 
-  file(READ "${RunCMake_TEST_BINARY_DIR}/lib/cmake/export-modules/cxx-modules/cxx-modules-${config}.cmake" config_script)
+  file(READ "${RunCMake_TEST_BINARY_DIR}/lib/cmake/export-modules/cxx-modules/cxx-modules-exp-${config}.cmake" config_script)
 
   if (NOT config_script MATCHES "include\\(\"\\\${CMAKE_CURRENT_LIST_DIR}/target-export-name-${config}\\.cmake\"\\)")
     list(APPEND RunCMake_TEST_FAILED

+ 40 - 0
Tests/RunCMake/CXXModules/ExportBuildCxxModulesTargets-check.cmake

@@ -0,0 +1,40 @@
+file(READ "${RunCMake_TEST_BINARY_DIR}/lib/cmake/export-modules/export-modules-targets.cmake" export_script)
+
+if (NOT export_script MATCHES [[include\("\${CMAKE_CURRENT_LIST_DIR}/cxx-modules/cxx-modules-7eb8e1b4d8a1\.cmake"\)]])
+  list(APPEND RunCMake_TEST_FAILED
+    "Could not find C++ module property script inclusion")
+endif ()
+
+file(READ "${RunCMake_TEST_BINARY_DIR}/lib/cmake/export-modules/cxx-modules/cxx-modules-7eb8e1b4d8a1.cmake" trampoline_script)
+
+if (RunCMake_GENERATOR_IS_MULTI_CONFIG)
+  if (NOT trampoline_script MATCHES [[include\("\${CMAKE_CURRENT_LIST_DIR}/cxx-modules-7eb8e1b4d8a1-[^.]*\.cmake" OPTIONAL\)]])
+    list(APPEND RunCMake_TEST_FAILED
+      "Could not find C++ module property per-config script inclusion(s)")
+  endif ()
+else ()
+  if (NOT trampoline_script MATCHES [[include\("\${CMAKE_CURRENT_LIST_DIR}/cxx-modules-7eb8e1b4d8a1-[^.]*\.cmake"\)]])
+    list(APPEND RunCMake_TEST_FAILED
+      "Could not find C++ module property per-config script inclusion(s)")
+  endif ()
+endif ()
+
+set(any_exists 0)
+foreach (config IN ITEMS noconfig Debug Release RelWithDebInfo MinSizeRel)
+  if (NOT EXISTS "${RunCMake_TEST_BINARY_DIR}/lib/cmake/export-modules/cxx-modules/cxx-modules-7eb8e1b4d8a1-${config}.cmake")
+    continue ()
+  endif ()
+  set(any_exists 1)
+
+  file(READ "${RunCMake_TEST_BINARY_DIR}/lib/cmake/export-modules/cxx-modules/cxx-modules-7eb8e1b4d8a1-${config}.cmake" config_script)
+
+  if (NOT config_script MATCHES "include\\(\"\\\${CMAKE_CURRENT_LIST_DIR}/target-export-name-${config}\\.cmake\"\\)")
+    list(APPEND RunCMake_TEST_FAILED
+      "Could not find C++ module per-target property script inclusion")
+  endif ()
+endforeach ()
+
+if (NOT any_exists)
+  list(APPEND RunCMake_TEST_FAILED
+    "No per-configuration target files exist.")
+endif ()

+ 21 - 0
Tests/RunCMake/CXXModules/ExportBuildCxxModulesTargets.cmake

@@ -0,0 +1,21 @@
+enable_language(CXX)
+set(CMAKE_CXX_SCANDEP_SOURCE "")
+
+add_library(export-modules)
+target_sources(export-modules
+  PUBLIC
+    FILE_SET fs TYPE CXX_MODULES FILES
+      sources/module.cxx)
+target_compile_features(export-modules
+  PRIVATE
+    cxx_std_20)
+set_property(TARGET export-modules
+  PROPERTY EXPORT_NAME export-name)
+
+install(TARGETS export-modules
+  EXPORT exp
+  FILE_SET fs DESTINATION "include/cxx/export-modules")
+
+export(TARGETS export-modules
+  FILE "${CMAKE_BINARY_DIR}/lib/cmake/export-modules/export-modules-targets.cmake"
+  CXX_MODULES_DIRECTORY "cxx-modules")

+ 5 - 5
Tests/RunCMake/CXXModules/ExportInstallCxxModules-check.cmake

@@ -1,25 +1,25 @@
 file(READ "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/Export/eee57a7e91412f1be699e9b63fa9d601/exp.cmake" export_script)
 
-if (NOT export_script MATCHES [[include\("\${CMAKE_CURRENT_LIST_DIR}/cxx-modules/cxx-modules\.cmake"\)]])
+if (NOT export_script MATCHES [[include\("\${CMAKE_CURRENT_LIST_DIR}/cxx-modules/cxx-modules-exp\.cmake"\)]])
   list(APPEND RunCMake_TEST_FAILED
     "Could not find C++ module property script inclusion")
 endif ()
 
-file(READ "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/Export/eee57a7e91412f1be699e9b63fa9d601/cxx-modules/cxx-modules.cmake" trampoline_script)
+file(READ "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/Export/eee57a7e91412f1be699e9b63fa9d601/cxx-modules/cxx-modules-exp.cmake" trampoline_script)
 
-if (NOT trampoline_script MATCHES [[file\(GLOB _cmake_cxx_module_includes "\${CMAKE_CURRENT_LIST_DIR}/cxx-modules-\*\.cmake"\)]])
+if (NOT trampoline_script MATCHES [[file\(GLOB _cmake_cxx_module_includes "\${CMAKE_CURRENT_LIST_DIR}/cxx-modules-exp-\*\.cmake"\)]])
   list(APPEND RunCMake_TEST_FAILED
     "Could not find C++ module property per-config script inclusion(s)")
 endif ()
 
 set(any_exists 0)
 foreach (config IN ITEMS noconfig Debug Release RelWithDebInfo MinSizeRel)
-  if (NOT EXISTS "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/Export/eee57a7e91412f1be699e9b63fa9d601/cxx-modules/cxx-modules-${config}.cmake")
+  if (NOT EXISTS "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/Export/eee57a7e91412f1be699e9b63fa9d601/cxx-modules/cxx-modules-exp-${config}.cmake")
     continue ()
   endif ()
   set(any_exists 1)
 
-  file(READ "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/Export/eee57a7e91412f1be699e9b63fa9d601/cxx-modules/cxx-modules-${config}.cmake" config_script)
+  file(READ "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/Export/eee57a7e91412f1be699e9b63fa9d601/cxx-modules/cxx-modules-exp-${config}.cmake" config_script)
 
   if (NOT config_script MATCHES "include\\(\"\\\${CMAKE_CURRENT_LIST_DIR}/target-export-name-${config}\\.cmake\"\\)")
     list(APPEND RunCMake_TEST_FAILED

+ 1 - 0
Tests/RunCMake/CXXModules/RunCMakeTest.cmake

@@ -88,6 +88,7 @@ run_cmake(InstallBMIGenericArgs)
 run_cmake(InstallBMIIgnore)
 
 run_cmake(ExportBuildCxxModules)
+run_cmake(ExportBuildCxxModulesTargets)
 run_cmake(ExportInstallCxxModules)
 
 # Generator-specific tests.