summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBen Boeckel <ben.boeckel@kitware.com>2023-09-24 20:04:20 (GMT)
committerBen Boeckel <ben.boeckel@kitware.com>2024-08-27 16:37:35 (GMT)
commitbea4fb7cd6de1ae7c7ce399ee8b38cc435cf1395 (patch)
tree1c2100eea6abba454d3525157323bffa2ff4fbf2
parent9c0491a3e41a0232ae10d53c0e12921bf1be4880 (diff)
downloadCMake-bea4fb7cd6de1ae7c7ce399ee8b38cc435cf1395.zip
CMake-bea4fb7cd6de1ae7c7ce399ee8b38cc435cf1395.tar.gz
CMake-bea4fb7cd6de1ae7c7ce399ee8b38cc435cf1395.tar.bz2
cmDyndepCollation: update template module database files if requested
-rw-r--r--Source/cmBuildDatabase.cxx34
-rw-r--r--Source/cmBuildDatabase.h8
-rw-r--r--Source/cmDyndepCollation.cxx77
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;
}