summaryrefslogtreecommitdiffstats
path: root/Source/cmExportInstallFileGenerator.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'Source/cmExportInstallFileGenerator.cxx')
-rw-r--r--Source/cmExportInstallFileGenerator.cxx108
1 files changed, 107 insertions, 1 deletions
diff --git a/Source/cmExportInstallFileGenerator.cxx b/Source/cmExportInstallFileGenerator.cxx
index adccdfe..7d8572d 100644
--- a/Source/cmExportInstallFileGenerator.cxx
+++ b/Source/cmExportInstallFileGenerator.cxx
@@ -7,6 +7,9 @@
#include <sstream>
#include <utility>
+#include <cm/string_view>
+#include <cmext/string_view>
+
#include "cmExportSet.h"
#include "cmFileSet.h"
#include "cmGeneratedFileStream.h"
@@ -18,6 +21,7 @@
#include "cmInstallTargetGenerator.h"
#include "cmLocalGenerator.h"
#include "cmMakefile.h"
+#include "cmMessageType.h"
#include "cmOutputConverter.h"
#include "cmPolicies.h"
#include "cmStateTypes.h"
@@ -162,10 +166,20 @@ bool cmExportInstallFileGenerator::GenerateMainFile(std::ostream& os)
this->LoadConfigFiles(os);
+ bool result = true;
+
+ this->GenerateCxxModuleInformation(os);
+ if (requiresConfigFiles) {
+ for (std::string const& c : this->Configurations) {
+ if (!this->GenerateImportCxxModuleConfigTargetInclusion(c)) {
+ result = false;
+ }
+ }
+ }
+
this->CleanupTemporaryVariables(os);
this->GenerateImportedFileCheckLoop(os);
- bool result = true;
// Generate an import file for each configuration.
// Don't do this if we only export INTERFACE_LIBRARY targets.
if (requiresConfigFiles) {
@@ -562,6 +576,21 @@ std::string cmExportInstallFileGenerator::GetFileSetDirectories(
cge->Evaluate(gte->LocalGenerator, config, gte),
cmOutputConverter::WrapQuotes::NoWrap));
+ auto const& type = fileSet->GetType();
+ // C++ modules do not support interface file sets which are dependent upon
+ // the configuration.
+ if (cge->GetHadContextSensitiveCondition() &&
+ (type == "CXX_MODULES"_s || type == "CXX_MODULE_HEADER_UNITS"_s)) {
+ auto* mf = this->IEGen->GetLocalGenerator()->GetMakefile();
+ std::ostringstream e;
+ e << "The \"" << gte->GetName() << "\" target's interface file set \""
+ << fileSet->GetName() << "\" of type \"" << type
+ << "\" contains context-sensitive base file entries which is not "
+ "supported.";
+ mf->IssueMessage(MessageType::FATAL_ERROR, e.str());
+ return std::string{};
+ }
+
if (cge->GetHadContextSensitiveCondition() && configs.size() != 1) {
resultVector.push_back(
cmStrCat("\"$<$<CONFIG:", config, ">:", dest, ">\""));
@@ -610,6 +639,21 @@ std::string cmExportInstallFileGenerator::GetFileSetFiles(
std::any_of(fileEntries.begin(), fileEntries.end(),
EntryIsContextSensitive);
+ auto const& type = fileSet->GetType();
+ // C++ modules do not support interface file sets which are dependent upon
+ // the configuration.
+ if (contextSensitive &&
+ (type == "CXX_MODULES"_s || type == "CXX_MODULE_HEADER_UNITS"_s)) {
+ auto* mf = this->IEGen->GetLocalGenerator()->GetMakefile();
+ std::ostringstream e;
+ e << "The \"" << gte->GetName() << "\" target's interface file set \""
+ << fileSet->GetName() << "\" of type \"" << type
+ << "\" contains context-sensitive base file entries which is not "
+ "supported.";
+ mf->IssueMessage(MessageType::FATAL_ERROR, e.str());
+ return std::string{};
+ }
+
for (auto const& it : files) {
auto prefix = it.first.empty() ? "" : cmStrCat(it.first, '/');
for (auto const& filename : it.second) {
@@ -635,3 +679,65 @@ std::string cmExportInstallFileGenerator::GetFileSetFiles(
return cmJoin(resultVector, " ");
}
+
+std::string cmExportInstallFileGenerator::GetCxxModulesDirectory() const
+{
+ return IEGen->GetCxxModuleDirectory();
+}
+
+void cmExportInstallFileGenerator::GenerateCxxModuleConfigInformation(
+ 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"
+ "foreach(_cmake_cxx_module_include IN LISTS _cmake_cxx_module_includes)\n"
+ " include(\"${_cmake_cxx_module_include}\")\n"
+ "endforeach()\n"
+ "unset(_cmake_cxx_module_include)\n"
+ "unset(_cmake_cxx_module_includes)\n";
+ /* clang-format on */
+}
+
+bool cmExportInstallFileGenerator::
+ GenerateImportCxxModuleConfigTargetInclusion(std::string const& config)
+{
+ auto cxx_modules_dirname = this->GetCxxModulesDirectory();
+ if (cxx_modules_dirname.empty()) {
+ return true;
+ }
+
+ std::string filename_config = config;
+ if (filename_config.empty()) {
+ filename_config = "noconfig";
+ }
+
+ std::string const dest =
+ cmStrCat(this->FileDir, '/', cxx_modules_dirname, '/');
+ std::string fileName =
+ cmStrCat(dest, "cxx-modules-", filename_config, ".cmake");
+
+ cmGeneratedFileStream os(fileName, true);
+ if (!os) {
+ std::string se = cmSystemTools::GetLastSystemError();
+ std::ostringstream e;
+ e << "cannot write to file \"" << fileName << "\": " << se;
+ cmSystemTools::Error(e.str());
+ return false;
+ }
+ os.SetCopyIfDifferent(true);
+
+ // Record this per-config import file.
+ this->ConfigCxxModuleFiles[config] = fileName;
+
+ auto& prop_files = this->ConfigCxxModuleTargetFiles[config];
+ for (auto const* tgt : this->ExportedTargets) {
+ auto prop_filename = cmStrCat("target-", tgt->GetExportName(), '-',
+ filename_config, ".cmake");
+ prop_files.emplace_back(cmStrCat(dest, prop_filename));
+ os << "include(\"${CMAKE_CURRENT_LIST_DIR}/" << prop_filename << "\")\n";
+ }
+
+ return true;
+}