diff options
author | Ben Boeckel <ben.boeckel@kitware.com> | 2023-09-24 20:04:20 (GMT) |
---|---|---|
committer | Ben Boeckel <ben.boeckel@kitware.com> | 2024-08-27 16:37:35 (GMT) |
commit | bea4fb7cd6de1ae7c7ce399ee8b38cc435cf1395 (patch) | |
tree | 1c2100eea6abba454d3525157323bffa2ff4fbf2 | |
parent | 9c0491a3e41a0232ae10d53c0e12921bf1be4880 (diff) | |
download | CMake-bea4fb7cd6de1ae7c7ce399ee8b38cc435cf1395.zip CMake-bea4fb7cd6de1ae7c7ce399ee8b38cc435cf1395.tar.gz CMake-bea4fb7cd6de1ae7c7ce399ee8b38cc435cf1395.tar.bz2 |
cmDyndepCollation: update template module database files if requested
-rw-r--r-- | Source/cmBuildDatabase.cxx | 34 | ||||
-rw-r--r-- | Source/cmBuildDatabase.h | 8 | ||||
-rw-r--r-- | Source/cmDyndepCollation.cxx | 77 |
3 files changed, 119 insertions, 0 deletions
diff --git a/Source/cmBuildDatabase.cxx b/Source/cmBuildDatabase.cxx index fafcee1..dc5f906 100644 --- a/Source/cmBuildDatabase.cxx +++ b/Source/cmBuildDatabase.cxx @@ -37,6 +37,40 @@ cmBuildDatabase::cmBuildDatabase() = default; cmBuildDatabase::cmBuildDatabase(cmBuildDatabase const&) = default; cmBuildDatabase::~cmBuildDatabase() = default; +cmBuildDatabase::LookupTable cmBuildDatabase::GenerateLookupTable() +{ + LookupTable lut; + + for (auto& Set_ : this->Sets) { + for (auto& TranslationUnit_ : Set_.TranslationUnits) { + // This table is from source path to TU instance. This is fine because a + // single target (where this is used) cannot contain the same source file + // multiple times. + lut[TranslationUnit_.Source] = &TranslationUnit_; + } + } + + return lut; +} + +bool cmBuildDatabase::HasPlaceholderNames() const +{ + for (auto const& Set_ : this->Sets) { + for (auto const& TranslationUnit_ : Set_.TranslationUnits) { + for (auto const& provide : TranslationUnit_.Provides) { + if (provide.first == PlaceholderName) { + return true; + } + if (provide.second == PlaceholderName) { + return true; + } + } + } + } + + return false; +} + void cmBuildDatabase::Write(std::string const& path) const { Json::Value mcdb = Json::objectValue; diff --git a/Source/cmBuildDatabase.h b/Source/cmBuildDatabase.h index 8ed35ec..a2733cb 100644 --- a/Source/cmBuildDatabase.h +++ b/Source/cmBuildDatabase.h @@ -41,6 +41,14 @@ public: cmBuildDatabase(cmBuildDatabase const&); ~cmBuildDatabase(); + using LookupTable = std::map<std::string, TranslationUnit*>; + // Generate a lookup table for the database. + // + // Only use when loading a single target's database in order to populate it. + LookupTable GenerateLookupTable(); + + bool HasPlaceholderNames() const; + void Write(std::string const& path) const; static std::unique_ptr<cmBuildDatabase> Load(std::string const& path); diff --git a/Source/cmDyndepCollation.cxx b/Source/cmDyndepCollation.cxx index cbb0e34..545782f 100644 --- a/Source/cmDyndepCollation.cxx +++ b/Source/cmDyndepCollation.cxx @@ -16,6 +16,7 @@ #include <cm3p/json/value.h> +#include "cmBuildDatabase.h" #include "cmExportBuildFileGenerator.h" #include "cmExportSet.h" #include "cmFileSet.h" @@ -344,6 +345,12 @@ struct CxxModuleFileSet cm::optional<std::string> Destination; }; +struct CxxModuleDatabaseInfo +{ + std::string TemplatePath; + std::string Output; +}; + struct CxxModuleBmiInstall { std::string Component; @@ -370,6 +377,7 @@ struct cmCxxModuleExportInfo { std::map<std::string, SourceInfo> ObjectToSource; std::map<std::string, CxxModuleFileSet> ObjectToFileSet; + cm::optional<CxxModuleDatabaseInfo> DatabaseInfo; cm::optional<CxxModuleBmiInstall> BmiInstallation; std::vector<CxxModuleExport> Exports; std::string Config; @@ -494,6 +502,21 @@ bool cmDyndepCollation::WriteDyndepMetadata( exports.emplace_back(std::move(properties), &exp); } + std::unique_ptr<cmBuildDatabase> module_database; + cmBuildDatabase::LookupTable build_database_lookup; + if (export_info.DatabaseInfo) { + module_database = + cmBuildDatabase::Load(export_info.DatabaseInfo->TemplatePath); + if (module_database) { + build_database_lookup = module_database->GenerateLookupTable(); + } else { + cmSystemTools::Error( + cmStrCat("Failed to read the template build database ", + export_info.DatabaseInfo->TemplatePath)); + result = false; + } + } + std::unique_ptr<cmGeneratedFileStream> bmi_install_script; if (export_info.BmiInstallation) { bmi_install_script = cm::make_unique<cmGeneratedFileStream>( @@ -523,6 +546,25 @@ bool cmDyndepCollation::WriteDyndepMetadata( #ifdef _WIN32 cmSystemTools::ConvertToUnixSlashes(output_path); #endif + + auto source_info_itr = export_info.ObjectToSource.find(output_path); + + // Update the module compilation database `requires` field if needed. + if (source_info_itr != export_info.ObjectToSource.end()) { + auto const& sourcePath = source_info_itr->second.SourcePath; + auto bdb_entry = build_database_lookup.find(sourcePath); + if (bdb_entry != build_database_lookup.end()) { + bdb_entry->second->Requires.clear(); + for (auto const& req : object.Requires) { + bdb_entry->second->Requires.push_back(req.LogicalName); + } + } else if (export_info.DatabaseInfo) { + cmSystemTools::Error( + cmStrCat("Failed to find module database entry for ", sourcePath)); + result = false; + } + } + // Find the fileset for this object. auto fileset_info_itr = export_info.ObjectToFileSet.find(output_path); bool const has_provides = !object.Provides.empty(); @@ -547,6 +589,31 @@ bool cmDyndepCollation::WriteDyndepMetadata( auto const& file_set = fileset_info_itr->second; + // Update the module compilation database `provides` field if needed. + { + auto bdb_entry = build_database_lookup.find(file_set.SourcePath); + if (bdb_entry != build_database_lookup.end()) { + // Clear the provides mapping; we will re-initialize it here. + if (!object.Provides.empty()) { + bdb_entry->second->Provides.clear(); + } + for (auto const& prov : object.Provides) { + auto bmiName = cb.ModuleFile(prov.LogicalName); + if (bmiName) { + bdb_entry->second->Provides[prov.LogicalName] = *bmiName; + } else { + cmSystemTools::Error( + cmStrCat("Failed to find BMI location for ", prov.LogicalName)); + result = false; + } + } + } else if (export_info.DatabaseInfo) { + cmSystemTools::Error(cmStrCat( + "Failed to find module database entry for ", file_set.SourcePath)); + result = false; + } + } + // Verify the fileset type for the object. if (file_set.Type == "CXX_MODULES"_s) { if (!has_provides) { @@ -708,6 +775,16 @@ bool cmDyndepCollation::WriteDyndepMetadata( } } + if (module_database) { + if (module_database->HasPlaceholderNames()) { + cmSystemTools::Error( + "Module compilation database still contains placeholders"); + result = false; + } else { + module_database->Write(export_info.DatabaseInfo->Output); + } + } + return result; } |