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

stage/master/nightly/2024/01/19
Brad King 2024-01-18 17:44:41 -05:00
commit 4cd153afe3
15 changed files with 134 additions and 45 deletions

View File

@ -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) {

View File

@ -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);

View File

@ -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,

View File

@ -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;
};

View File

@ -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) {

View File

@ -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
{

View File

@ -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,

View File

@ -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));

View File

@ -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");
}

View File

@ -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();

View File

@ -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

View File

@ -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 ()

View File

@ -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")

View File

@ -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

View File

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