summaryrefslogtreecommitdiffstats
path: root/Source
diff options
context:
space:
mode:
Diffstat (limited to 'Source')
-rw-r--r--Source/cmDyndepCollation.cxx336
-rw-r--r--Source/cmDyndepCollation.h50
-rw-r--r--Source/cmGlobalNinjaGenerator.cxx282
3 files changed, 355 insertions, 313 deletions
diff --git a/Source/cmDyndepCollation.cxx b/Source/cmDyndepCollation.cxx
index f933e2a..2827659 100644
--- a/Source/cmDyndepCollation.cxx
+++ b/Source/cmDyndepCollation.cxx
@@ -5,6 +5,8 @@
#include <algorithm>
#include <map>
+#include <ostream>
+#include <set>
#include <utility>
#include <vector>
@@ -17,6 +19,7 @@
#include "cmExportBuildFileGenerator.h"
#include "cmExportSet.h"
#include "cmFileSet.h"
+#include "cmGeneratedFileStream.h"
#include "cmGeneratorExpression.h" // IWYU pragma: keep
#include "cmGeneratorTarget.h"
#include "cmGlobalGenerator.h"
@@ -26,6 +29,8 @@
#include "cmInstallGenerator.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
+#include "cmOutputConverter.h"
+#include "cmScanDepFormat.h"
#include "cmSourceFile.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
@@ -261,10 +266,56 @@ void cmDyndepCollation::AddCollationInformation(
tdi["config"] = config;
}
-std::unique_ptr<cmCxxModuleExportInfo> cmDyndepCollation::ParseExportInfo(
- Json::Value const& tdi)
+struct CxxModuleFileSet
{
- auto export_info = cm::make_unique<cmCxxModuleExportInfo>();
+ std::string Name;
+ std::string RelativeDirectory;
+ std::string SourcePath;
+ std::string Type;
+ cmFileSetVisibility Visibility;
+ cm::optional<std::string> Destination;
+};
+
+struct CxxModuleBmiInstall
+{
+ std::string Component;
+ std::string Destination;
+ bool ExcludeFromAll;
+ bool Optional;
+ std::string Permissions;
+ std::string MessageLevel;
+ std::string ScriptLocation;
+};
+
+struct CxxModuleExport
+{
+ std::string Name;
+ std::string Destination;
+ std::string Prefix;
+ std::string CxxModuleInfoDir;
+ std::string Namespace;
+ bool Install;
+};
+
+struct cmCxxModuleExportInfo
+{
+ std::map<std::string, CxxModuleFileSet> ObjectToFileSet;
+ cm::optional<CxxModuleBmiInstall> BmiInstallation;
+ std::vector<CxxModuleExport> Exports;
+ std::string Config;
+};
+
+void cmCxxModuleExportInfoDeleter::operator()(cmCxxModuleExportInfo* ei) const
+{
+ delete ei;
+}
+
+std::unique_ptr<cmCxxModuleExportInfo, cmCxxModuleExportInfoDeleter>
+cmDyndepCollation::ParseExportInfo(Json::Value const& tdi)
+{
+ auto export_info =
+ std::unique_ptr<cmCxxModuleExportInfo, cmCxxModuleExportInfoDeleter>(
+ new cmCxxModuleExportInfo);
export_info->Config = tdi["config"].asString();
if (export_info->Config.empty()) {
@@ -320,3 +371,282 @@ std::unique_ptr<cmCxxModuleExportInfo> cmDyndepCollation::ParseExportInfo(
return export_info;
}
+
+bool cmDyndepCollation::WriteDyndepMetadata(
+ std::string const& lang, std::vector<cmScanDepInfo> const& objects,
+ cmCxxModuleExportInfo const& export_info,
+ cmDyndepMetadataCallbacks const& cb)
+{
+ // Only C++ supports any of the file-set or BMI installation considered
+ // below.
+ if (lang != "CXX"_s) {
+ return true;
+ }
+
+ bool result = true;
+
+ // Prepare the export information blocks.
+ std::string const config_upper =
+ cmSystemTools::UpperCase(export_info.Config);
+ std::vector<
+ std::pair<std::unique_ptr<cmGeneratedFileStream>, CxxModuleExport const*>>
+ exports;
+ for (auto const& exp : export_info.Exports) {
+ std::unique_ptr<cmGeneratedFileStream> properties;
+
+ std::string const export_dir =
+ cmStrCat(exp.Prefix, '/', exp.CxxModuleInfoDir, '/');
+ std::string const property_file_path = cmStrCat(
+ export_dir, "target-", exp.Name, '-', export_info.Config, ".cmake");
+ properties = cm::make_unique<cmGeneratedFileStream>(property_file_path);
+
+ // Set up the preamble.
+ *properties << "set_property(TARGET \"" << exp.Namespace << exp.Name
+ << "\"\n"
+ << " PROPERTY IMPORTED_CXX_MODULES_" << config_upper << '\n';
+
+ exports.emplace_back(std::move(properties), &exp);
+ }
+
+ std::unique_ptr<cmGeneratedFileStream> bmi_install_script;
+ if (export_info.BmiInstallation) {
+ bmi_install_script = cm::make_unique<cmGeneratedFileStream>(
+ export_info.BmiInstallation->ScriptLocation);
+ }
+
+ auto cmEscape = [](cm::string_view str) {
+ return cmOutputConverter::EscapeForCMake(
+ str, cmOutputConverter::WrapQuotes::NoWrap);
+ };
+ auto install_destination =
+ [&cmEscape](std::string const& dest) -> std::pair<bool, std::string> {
+ if (cmSystemTools::FileIsFullPath(dest)) {
+ return std::make_pair(true, cmEscape(dest));
+ }
+ return std::make_pair(false,
+ cmStrCat("${_IMPORT_PREFIX}/", cmEscape(dest)));
+ };
+
+ // public/private requirement tracking.
+ std::set<std::string> private_modules;
+ std::map<std::string, std::set<std::string>> public_source_requires;
+
+ for (cmScanDepInfo const& object : objects) {
+ // Convert to forward slashes.
+ auto output_path = object.PrimaryOutput;
+#ifdef _WIN32
+ cmSystemTools::ConvertToUnixSlashes(output_path);
+#endif
+ // Find the fileset for this object.
+ auto fileset_info_itr = export_info.ObjectToFileSet.find(output_path);
+ bool const has_provides = !object.Provides.empty();
+ if (fileset_info_itr == export_info.ObjectToFileSet.end()) {
+ // If it provides anything, it should have a `CXX_MODULES` or
+ // `CXX_MODULE_INTERNAL_PARTITIONS` type and be present.
+ if (has_provides) {
+ // Take the first module provided to provide context.
+ auto const& provides = object.Provides[0];
+ char const* ok_types = "`CXX_MODULES`";
+ if (provides.LogicalName.find(':') != std::string::npos) {
+ ok_types = "`CXX_MODULES` (or `CXX_MODULE_INTERNAL_PARTITIONS` if "
+ "it is not `export`ed)";
+ }
+ cmSystemTools::Error(cmStrCat(
+ "Output ", object.PrimaryOutput, " provides the `",
+ provides.LogicalName,
+ "` module but it is not found in a `FILE_SET` of type ", ok_types));
+ result = false;
+ }
+
+ // This object file does not provide anything, so nothing more needs to
+ // be done.
+ continue;
+ }
+
+ auto const& file_set = fileset_info_itr->second;
+
+ // Verify the fileset type for the object.
+ if (file_set.Type == "CXX_MODULES"_s) {
+ if (!has_provides) {
+ cmSystemTools::Error(
+ cmStrCat("Output ", object.PrimaryOutput,
+ " is of type `CXX_MODULES` but does not provide a module"));
+ result = false;
+ continue;
+ }
+ } else if (file_set.Type == "CXX_MODULE_INTERNAL_PARTITIONS"_s) {
+ if (!has_provides) {
+ cmSystemTools::Error(
+ cmStrCat("Source ", file_set.SourcePath,
+ " is of type `CXX_MODULE_INTERNAL_PARTITIONS` but does not "
+ "provide a module"));
+ result = false;
+ continue;
+ }
+ auto const& provides = object.Provides[0];
+ if (provides.LogicalName.find(':') == std::string::npos) {
+ cmSystemTools::Error(
+ cmStrCat("Source ", file_set.SourcePath,
+ " is of type `CXX_MODULE_INTERNAL_PARTITIONS` but does not "
+ "provide a module partition"));
+ result = false;
+ continue;
+ }
+ } else if (file_set.Type == "CXX_MODULE_HEADERS"_s) {
+ // TODO.
+ } else {
+ if (has_provides) {
+ auto const& provides = object.Provides[0];
+ char const* ok_types = "`CXX_MODULES`";
+ if (provides.LogicalName.find(':') != std::string::npos) {
+ ok_types = "`CXX_MODULES` (or `CXX_MODULE_INTERNAL_PARTITIONS` if "
+ "it is not `export`ed)";
+ }
+ cmSystemTools::Error(
+ cmStrCat("Source ", file_set.SourcePath, " provides the `",
+ provides.LogicalName, "` C++ module but is of type `",
+ file_set.Type, "` module but must be of type ", ok_types));
+ result = false;
+ }
+
+ // Not a C++ module; ignore.
+ continue;
+ }
+
+ if (!cmFileSetVisibilityIsForInterface(file_set.Visibility)) {
+ // Nothing needs to be conveyed about non-`PUBLIC` modules.
+ for (auto const& p : object.Provides) {
+ private_modules.insert(p.LogicalName);
+ }
+ continue;
+ }
+
+ // The module is public. Record what it directly requires.
+ {
+ auto& reqs = public_source_requires[file_set.SourcePath];
+ for (auto const& r : object.Requires) {
+ reqs.insert(r.LogicalName);
+ }
+ }
+
+ // Write out properties and install rules for any exports.
+ for (auto const& p : object.Provides) {
+ bool bmi_dest_is_abs = false;
+ std::string bmi_destination;
+ if (export_info.BmiInstallation) {
+ auto dest =
+ install_destination(export_info.BmiInstallation->Destination);
+ bmi_dest_is_abs = dest.first;
+ bmi_destination = cmStrCat(dest.second, '/');
+ }
+
+ std::string install_bmi_path;
+ std::string build_bmi_path;
+ auto m = cb.ModuleFile(p.LogicalName);
+ if (m) {
+ install_bmi_path = cmStrCat(
+ bmi_destination, cmEscape(cmSystemTools::GetFilenameName(*m)));
+ build_bmi_path = cmEscape(*m);
+ }
+
+ for (auto const& exp : exports) {
+ std::string iface_source;
+ if (exp.second->Install && file_set.Destination) {
+ auto dest = install_destination(*file_set.Destination);
+ iface_source = cmStrCat(
+ dest.second, '/', cmEscape(file_set.RelativeDirectory),
+ cmEscape(cmSystemTools::GetFilenameName(file_set.SourcePath)));
+ } else {
+ iface_source = cmEscape(file_set.SourcePath);
+ }
+
+ std::string bmi_path;
+ if (exp.second->Install && export_info.BmiInstallation) {
+ bmi_path = install_bmi_path;
+ } else if (!exp.second->Install) {
+ bmi_path = build_bmi_path;
+ }
+
+ if (iface_source.empty()) {
+ // No destination for the C++ module source; ignore this property
+ // value.
+ continue;
+ }
+
+ *exp.first << " \"" << cmEscape(p.LogicalName) << '='
+ << iface_source;
+ if (!bmi_path.empty()) {
+ *exp.first << ',' << bmi_path;
+ }
+ *exp.first << "\"\n";
+ }
+
+ if (bmi_install_script) {
+ auto const& bmi_install = *export_info.BmiInstallation;
+
+ *bmi_install_script << "if (CMAKE_INSTALL_COMPONENT STREQUAL \""
+ << cmEscape(bmi_install.Component) << '\"';
+ if (!bmi_install.ExcludeFromAll) {
+ *bmi_install_script << " OR NOT CMAKE_INSTALL_COMPONENT";
+ }
+ *bmi_install_script << ")\n";
+ *bmi_install_script << " file(INSTALL\n"
+ " DESTINATION \"";
+ if (!bmi_dest_is_abs) {
+ *bmi_install_script << "${CMAKE_INSTALL_PREFIX}/";
+ }
+ *bmi_install_script << cmEscape(bmi_install.Destination)
+ << "\"\n"
+ " TYPE FILE\n";
+ if (bmi_install.Optional) {
+ *bmi_install_script << " OPTIONAL\n";
+ }
+ if (!bmi_install.MessageLevel.empty()) {
+ *bmi_install_script << " " << bmi_install.MessageLevel << "\n";
+ }
+ if (!bmi_install.Permissions.empty()) {
+ *bmi_install_script << " PERMISSIONS" << bmi_install.Permissions
+ << "\n";
+ }
+ *bmi_install_script << " FILES \"" << *m << "\")\n";
+ if (bmi_dest_is_abs) {
+ *bmi_install_script
+ << " list(APPEND CMAKE_ABSOLUTE_DESTINATION_FILES\n"
+ " \""
+ << cmEscape(cmSystemTools::GetFilenameName(*m))
+ << "\")\n"
+ " if (CMAKE_WARN_ON_ABSOLUTE_INSTALL_DESTINATION)\n"
+ " message(WARNING\n"
+ " \"ABSOLUTE path INSTALL DESTINATION : "
+ "${CMAKE_ABSOLUTE_DESTINATION_FILES}\")\n"
+ " endif ()\n"
+ " if (CMAKE_ERROR_ON_ABSOLUTE_INSTALL_DESTINATION)\n"
+ " message(FATAL_ERROR\n"
+ " \"ABSOLUTE path INSTALL DESTINATION forbidden (by "
+ "caller): ${CMAKE_ABSOLUTE_DESTINATION_FILES}\")\n"
+ " endif ()\n";
+ }
+ *bmi_install_script << "endif ()\n";
+ }
+ }
+ }
+
+ // Add trailing parenthesis for the `set_property` call.
+ for (auto const& exp : exports) {
+ *exp.first << ")\n";
+ }
+
+ // Check that public sources only require public modules.
+ for (auto const& pub_reqs : public_source_requires) {
+ for (auto const& req : pub_reqs.second) {
+ if (private_modules.count(req)) {
+ cmSystemTools::Error(cmStrCat(
+ "Public C++ module source `", pub_reqs.first, "` requires the `",
+ req, "` C++ module which is provided by a private source"));
+ result = false;
+ }
+ }
+ }
+
+ return result;
+}
diff --git a/Source/cmDyndepCollation.h b/Source/cmDyndepCollation.h
index 5f78707..e70ac09 100644
--- a/Source/cmDyndepCollation.h
+++ b/Source/cmDyndepCollation.h
@@ -5,16 +5,14 @@
#include "cmConfigure.h" // IWYU pragma: keep
#include <functional>
-#include <map>
#include <memory>
#include <string>
#include <vector>
#include <cm/optional>
-#include "cmFileSet.h"
-
class cmGeneratorTarget;
+struct cmScanDepInfo;
class cmSourceFile;
namespace Json {
@@ -27,43 +25,15 @@ struct cmDyndepGeneratorCallbacks
ObjectFilePath;
};
-struct CxxModuleFileSet
-{
- std::string Name;
- std::string RelativeDirectory;
- std::string SourcePath;
- std::string Type;
- cmFileSetVisibility Visibility;
- cm::optional<std::string> Destination;
-};
-
-struct CxxModuleBmiInstall
-{
- std::string Component;
- std::string Destination;
- bool ExcludeFromAll;
- bool Optional;
- std::string Permissions;
- std::string MessageLevel;
- std::string ScriptLocation;
-};
-
-struct CxxModuleExport
+struct cmDyndepMetadataCallbacks
{
- std::string Name;
- std::string Destination;
- std::string Prefix;
- std::string CxxModuleInfoDir;
- std::string Namespace;
- bool Install;
+ std::function<cm::optional<std::string>(std::string const& name)> ModuleFile;
};
-struct cmCxxModuleExportInfo
+struct cmCxxModuleExportInfo;
+struct cmCxxModuleExportInfoDeleter
{
- std::map<std::string, CxxModuleFileSet> ObjectToFileSet;
- cm::optional<CxxModuleBmiInstall> BmiInstallation;
- std::vector<CxxModuleExport> Exports;
- std::string Config;
+ void operator()(cmCxxModuleExportInfo* ei) const;
};
struct cmDyndepCollation
@@ -73,6 +43,10 @@ struct cmDyndepCollation
std::string const& config,
cmDyndepGeneratorCallbacks const& cb);
- static std::unique_ptr<cmCxxModuleExportInfo> ParseExportInfo(
- Json::Value const& tdi);
+ static std::unique_ptr<cmCxxModuleExportInfo, cmCxxModuleExportInfoDeleter>
+ ParseExportInfo(Json::Value const& tdi);
+ static bool WriteDyndepMetadata(std::string const& lang,
+ std::vector<cmScanDepInfo> const& objects,
+ cmCxxModuleExportInfo const& export_info,
+ cmDyndepMetadataCallbacks const& cb);
};
diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx
index cd8d9d5..4500f33 100644
--- a/Source/cmGlobalNinjaGenerator.cxx
+++ b/Source/cmGlobalNinjaGenerator.cxx
@@ -26,7 +26,6 @@
#include "cmCxxModuleMapper.h"
#include "cmDyndepCollation.h"
-#include "cmFileSet.h"
#include "cmFortranParser.h"
#include "cmGeneratedFileStream.h"
#include "cmGeneratorExpressionEvaluationFile.h"
@@ -2711,279 +2710,18 @@ bool cmGlobalNinjaGenerator::WriteDyndepFile(
cmGeneratedFileStream tmf(target_mods_file);
tmf << target_module_info;
- bool result = true;
-
- // Fortran doesn't support any of the file-set or BMI installation considered
- // below.
- if (arg_lang != "Fortran"_s) {
- // Prepare the export information blocks.
- std::string const config_upper =
- cmSystemTools::UpperCase(export_info.Config);
- std::vector<std::pair<std::unique_ptr<cmGeneratedFileStream>,
- CxxModuleExport const*>>
- exports;
- for (auto const& exp : export_info.Exports) {
- std::unique_ptr<cmGeneratedFileStream> properties;
-
- std::string const export_dir =
- cmStrCat(exp.Prefix, '/', exp.CxxModuleInfoDir, '/');
- std::string const property_file_path = cmStrCat(
- export_dir, "target-", exp.Name, '-', export_info.Config, ".cmake");
- properties = cm::make_unique<cmGeneratedFileStream>(property_file_path);
-
- // Set up the preamble.
- *properties << "set_property(TARGET \"" << exp.Namespace << exp.Name
- << "\"\n"
- << " PROPERTY IMPORTED_CXX_MODULES_" << config_upper
- << '\n';
-
- exports.emplace_back(std::move(properties), &exp);
- }
-
- std::unique_ptr<cmGeneratedFileStream> bmi_install_script;
- if (export_info.BmiInstallation) {
- bmi_install_script = cm::make_unique<cmGeneratedFileStream>(
- export_info.BmiInstallation->ScriptLocation);
+ cmDyndepMetadataCallbacks cb;
+ cb.ModuleFile =
+ [mod_files](std::string const& name) -> cm::optional<std::string> {
+ auto m = mod_files.find(name);
+ if (m != mod_files.end()) {
+ return m->second;
}
+ return {};
+ };
- auto cmEscape = [](cm::string_view str) {
- return cmOutputConverter::EscapeForCMake(
- str, cmOutputConverter::WrapQuotes::NoWrap);
- };
- auto install_destination =
- [&cmEscape](std::string const& dest) -> std::pair<bool, std::string> {
- if (cmSystemTools::FileIsFullPath(dest)) {
- return std::make_pair(true, cmEscape(dest));
- }
- return std::make_pair(false,
- cmStrCat("${_IMPORT_PREFIX}/", cmEscape(dest)));
- };
-
- // public/private requirement tracking.
- std::set<std::string> private_modules;
- std::map<std::string, std::set<std::string>> public_source_requires;
-
- for (cmScanDepInfo const& object : objects) {
- // Convert to forward slashes.
- auto output_path = object.PrimaryOutput;
-# ifdef _WIN32
- cmSystemTools::ConvertToUnixSlashes(output_path);
-# endif
- // Find the fileset for this object.
- auto fileset_info_itr = export_info.ObjectToFileSet.find(output_path);
- bool const has_provides = !object.Provides.empty();
- if (fileset_info_itr == export_info.ObjectToFileSet.end()) {
- // If it provides anything, it should have a `CXX_MODULES` or
- // `CXX_MODULE_INTERNAL_PARTITIONS` type and be present.
- if (has_provides) {
- // Take the first module provided to provide context.
- auto const& provides = object.Provides[0];
- char const* ok_types = "`CXX_MODULES`";
- if (provides.LogicalName.find(':') != std::string::npos) {
- ok_types = "`CXX_MODULES` (or `CXX_MODULE_INTERNAL_PARTITIONS` if "
- "it is not `export`ed)";
- }
- cmSystemTools::Error(
- cmStrCat("Output ", object.PrimaryOutput, " provides the `",
- provides.LogicalName,
- "` module but it is not found in a `FILE_SET` of type ",
- ok_types));
- result = false;
- }
-
- // This object file does not provide anything, so nothing more needs to
- // be done.
- continue;
- }
-
- auto const& file_set = fileset_info_itr->second;
-
- // Verify the fileset type for the object.
- if (file_set.Type == "CXX_MODULES"_s) {
- if (!has_provides) {
- cmSystemTools::Error(cmStrCat(
- "Output ", object.PrimaryOutput,
- " is of type `CXX_MODULES` but does not provide a module"));
- result = false;
- continue;
- }
- } else if (file_set.Type == "CXX_MODULE_INTERNAL_PARTITIONS"_s) {
- if (!has_provides) {
- cmSystemTools::Error(cmStrCat(
- "Source ", file_set.SourcePath,
- " is of type `CXX_MODULE_INTERNAL_PARTITIONS` but does not "
- "provide a module"));
- result = false;
- continue;
- }
- auto const& provides = object.Provides[0];
- if (provides.LogicalName.find(':') == std::string::npos) {
- cmSystemTools::Error(cmStrCat(
- "Source ", file_set.SourcePath,
- " is of type `CXX_MODULE_INTERNAL_PARTITIONS` but does not "
- "provide a module partition"));
- result = false;
- continue;
- }
- } else if (file_set.Type == "CXX_MODULE_HEADERS"_s) {
- // TODO.
- } else {
- if (has_provides) {
- auto const& provides = object.Provides[0];
- char const* ok_types = "`CXX_MODULES`";
- if (provides.LogicalName.find(':') != std::string::npos) {
- ok_types = "`CXX_MODULES` (or `CXX_MODULE_INTERNAL_PARTITIONS` if "
- "it is not `export`ed)";
- }
- cmSystemTools::Error(cmStrCat(
- "Source ", file_set.SourcePath, " provides the `",
- provides.LogicalName, "` C++ module but is of type `",
- file_set.Type, "` module but must be of type ", ok_types));
- result = false;
- }
-
- // Not a C++ module; ignore.
- continue;
- }
-
- if (!cmFileSetVisibilityIsForInterface(file_set.Visibility)) {
- // Nothing needs to be conveyed about non-`PUBLIC` modules.
- for (auto const& p : object.Provides) {
- private_modules.insert(p.LogicalName);
- }
- continue;
- }
-
- // The module is public. Record what it directly requires.
- {
- auto& reqs = public_source_requires[file_set.SourcePath];
- for (auto const& r : object.Requires) {
- reqs.insert(r.LogicalName);
- }
- }
-
- // Write out properties and install rules for any exports.
- for (auto const& p : object.Provides) {
- bool bmi_dest_is_abs = false;
- std::string bmi_destination;
- if (export_info.BmiInstallation) {
- auto dest =
- install_destination(export_info.BmiInstallation->Destination);
- bmi_dest_is_abs = dest.first;
- bmi_destination = cmStrCat(dest.second, '/');
- }
-
- std::string install_bmi_path;
- std::string build_bmi_path;
- auto m = mod_files.find(p.LogicalName);
- if (m != mod_files.end()) {
- install_bmi_path =
- cmStrCat(bmi_destination,
- cmEscape(cmSystemTools::GetFilenameName(m->second)));
- build_bmi_path = cmEscape(m->second);
- }
-
- for (auto const& exp : exports) {
- std::string iface_source;
- if (exp.second->Install && file_set.Destination) {
- auto dest = install_destination(*file_set.Destination);
- iface_source = cmStrCat(
- dest.second, '/', cmEscape(file_set.RelativeDirectory),
- cmEscape(cmSystemTools::GetFilenameName(file_set.SourcePath)));
- } else {
- iface_source = cmEscape(file_set.SourcePath);
- }
-
- std::string bmi_path;
- if (exp.second->Install && export_info.BmiInstallation) {
- bmi_path = install_bmi_path;
- } else if (!exp.second->Install) {
- bmi_path = build_bmi_path;
- }
-
- if (iface_source.empty()) {
- // No destination for the C++ module source; ignore this property
- // value.
- continue;
- }
-
- *exp.first << " \"" << cmEscape(p.LogicalName) << '='
- << iface_source;
- if (!bmi_path.empty()) {
- *exp.first << ',' << bmi_path;
- }
- *exp.first << "\"\n";
- }
-
- if (bmi_install_script) {
- auto const& bmi_install = *export_info.BmiInstallation;
-
- *bmi_install_script << "if (CMAKE_INSTALL_COMPONENT STREQUAL \""
- << cmEscape(bmi_install.Component) << '\"';
- if (!bmi_install.ExcludeFromAll) {
- *bmi_install_script << " OR NOT CMAKE_INSTALL_COMPONENT";
- }
- *bmi_install_script << ")\n";
- *bmi_install_script << " file(INSTALL\n"
- " DESTINATION \"";
- if (!bmi_dest_is_abs) {
- *bmi_install_script << "${CMAKE_INSTALL_PREFIX}/";
- }
- *bmi_install_script << cmEscape(bmi_install.Destination)
- << "\"\n"
- " TYPE FILE\n";
- if (bmi_install.Optional) {
- *bmi_install_script << " OPTIONAL\n";
- }
- if (!bmi_install.MessageLevel.empty()) {
- *bmi_install_script << " " << bmi_install.MessageLevel << "\n";
- }
- if (!bmi_install.Permissions.empty()) {
- *bmi_install_script << " PERMISSIONS" << bmi_install.Permissions
- << "\n";
- }
- *bmi_install_script << " FILES \"" << m->second << "\")\n";
- if (bmi_dest_is_abs) {
- *bmi_install_script
- << " list(APPEND CMAKE_ABSOLUTE_DESTINATION_FILES\n"
- " \""
- << cmEscape(cmSystemTools::GetFilenameName(m->second))
- << "\")\n"
- " if (CMAKE_WARN_ON_ABSOLUTE_INSTALL_DESTINATION)\n"
- " message(WARNING\n"
- " \"ABSOLUTE path INSTALL DESTINATION : "
- "${CMAKE_ABSOLUTE_DESTINATION_FILES}\")\n"
- " endif ()\n"
- " if (CMAKE_ERROR_ON_ABSOLUTE_INSTALL_DESTINATION)\n"
- " message(FATAL_ERROR\n"
- " \"ABSOLUTE path INSTALL DESTINATION forbidden (by "
- "caller): ${CMAKE_ABSOLUTE_DESTINATION_FILES}\")\n"
- " endif ()\n";
- }
- *bmi_install_script << "endif ()\n";
- }
- }
- }
-
- // Add trailing parenthesis for the `set_property` call.
- for (auto const& exp : exports) {
- *exp.first << ")\n";
- }
-
- // Check that public sources only require public modules.
- for (auto const& pub_reqs : public_source_requires) {
- for (auto const& req : pub_reqs.second) {
- if (private_modules.count(req)) {
- cmSystemTools::Error(cmStrCat(
- "Public C++ module source `", pub_reqs.first, "` requires the `",
- req, "` C++ module which is provided by a private source"));
- result = false;
- }
- }
- }
- }
-
- return result;
+ return cmDyndepCollation::WriteDyndepMetadata(arg_lang, objects, export_info,
+ cb);
}
int cmcmd_cmake_ninja_dyndep(std::vector<std::string>::const_iterator argBeg,