| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690 |
- /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
- file Copyright.txt or https://cmake.org/licensing for details. */
- #include "cmDyndepCollation.h"
- #include <algorithm>
- #include <map>
- #include <ostream>
- #include <set>
- #include <utility>
- #include <vector>
- #include <cm/memory>
- #include <cm/string_view>
- #include <cmext/string_view>
- #include <cm3p/json/value.h>
- #include "cmExportBuildFileGenerator.h"
- #include "cmExportSet.h"
- #include "cmFileSet.h"
- #include "cmGeneratedFileStream.h"
- #include "cmGeneratorExpression.h" // IWYU pragma: keep
- #include "cmGeneratorTarget.h"
- #include "cmGlobalGenerator.h"
- #include "cmInstallCxxModuleBmiGenerator.h"
- #include "cmInstallExportGenerator.h"
- #include "cmInstallFileSetGenerator.h"
- #include "cmInstallGenerator.h"
- #include "cmMakefile.h"
- #include "cmMessageType.h"
- #include "cmOutputConverter.h"
- #include "cmScanDepFormat.h"
- #include "cmSourceFile.h"
- #include "cmStringAlgorithms.h"
- #include "cmSystemTools.h"
- #include "cmTarget.h"
- #include "cmTargetExport.h"
- namespace {
- Json::Value CollationInformationCxxModules(
- cmGeneratorTarget const* gt, std::string const& config,
- cmDyndepGeneratorCallbacks const& cb)
- {
- cmTarget const* tgt = gt->Target;
- auto all_file_sets = tgt->GetAllFileSetNames();
- Json::Value tdi_cxx_module_info = Json::objectValue;
- for (auto const& file_set_name : all_file_sets) {
- auto const* file_set = tgt->GetFileSet(file_set_name);
- if (!file_set) {
- gt->Makefile->IssueMessage(MessageType::INTERNAL_ERROR,
- cmStrCat("Target \"", tgt->GetName(),
- "\" is tracked to have file set \"",
- file_set_name,
- "\", but it was not found."));
- continue;
- }
- auto fs_type = file_set->GetType();
- // We only care about C++ module sources here.
- if (fs_type != "CXX_MODULES"_s) {
- continue;
- }
- auto fileEntries = file_set->CompileFileEntries();
- auto directoryEntries = file_set->CompileDirectoryEntries();
- auto directories = file_set->EvaluateDirectoryEntries(
- directoryEntries, gt->LocalGenerator, config, gt);
- std::map<std::string, std::vector<std::string>> files_per_dirs;
- for (auto const& entry : fileEntries) {
- file_set->EvaluateFileEntry(directories, files_per_dirs, entry,
- gt->LocalGenerator, config, gt);
- }
- enum class CompileType
- {
- ObjectAndBmi,
- BmiOnly,
- };
- std::map<std::string, std::pair<cmSourceFile const*, CompileType>> sf_map;
- {
- auto fill_sf_map = [gt, tgt, &sf_map](cmSourceFile const* sf,
- CompileType type) {
- auto full_path = sf->GetFullPath();
- if (full_path.empty()) {
- gt->Makefile->IssueMessage(
- MessageType::INTERNAL_ERROR,
- cmStrCat("Target \"", tgt->GetName(),
- "\" has a full path-less source file."));
- return;
- }
- sf_map[full_path] = std::make_pair(sf, type);
- };
- std::vector<cmSourceFile const*> objectSources;
- gt->GetObjectSources(objectSources, config);
- for (auto const* sf : objectSources) {
- fill_sf_map(sf, CompileType::ObjectAndBmi);
- }
- std::vector<cmSourceFile const*> cxxModuleSources;
- gt->GetCxxModuleSources(cxxModuleSources, config);
- for (auto const* sf : cxxModuleSources) {
- fill_sf_map(sf, CompileType::BmiOnly);
- }
- }
- Json::Value fs_dest = Json::nullValue;
- for (auto const& ig : gt->Makefile->GetInstallGenerators()) {
- if (auto const* fsg =
- dynamic_cast<cmInstallFileSetGenerator const*>(ig.get())) {
- if (fsg->GetTarget() == gt && fsg->GetFileSet() == file_set) {
- fs_dest = fsg->GetDestination(config);
- continue;
- }
- }
- }
- for (auto const& files_per_dir : files_per_dirs) {
- for (auto const& file : files_per_dir.second) {
- auto const full_file = cmSystemTools::CollapseFullPath(file);
- auto lookup = sf_map.find(full_file);
- if (lookup == sf_map.end()) {
- gt->Makefile->IssueMessage(
- MessageType::FATAL_ERROR,
- cmStrCat("Target \"", tgt->GetName(), "\" has source file\n ",
- file,
- "\nin a \"FILE_SET TYPE CXX_MODULES\" but it is not "
- "scheduled for compilation."));
- continue;
- }
- auto const* sf = lookup->second.first;
- CompileType const ct = lookup->second.second;
- if (!sf) {
- gt->Makefile->IssueMessage(
- MessageType::INTERNAL_ERROR,
- cmStrCat("Target \"", tgt->GetName(), "\" has source file \"",
- file, "\" which has not been tracked properly."));
- continue;
- }
- auto obj_path = ct == CompileType::ObjectAndBmi
- ? cb.ObjectFilePath(sf, config)
- : cb.BmiFilePath(sf, config);
- Json::Value& tdi_module_info = tdi_cxx_module_info[obj_path] =
- Json::objectValue;
- tdi_module_info["source"] = full_file;
- tdi_module_info["bmi-only"] = ct == CompileType::BmiOnly;
- tdi_module_info["relative-directory"] = files_per_dir.first;
- tdi_module_info["name"] = file_set->GetName();
- tdi_module_info["type"] = file_set->GetType();
- tdi_module_info["visibility"] =
- std::string(cmFileSetVisibilityToName(file_set->GetVisibility()));
- tdi_module_info["destination"] = fs_dest;
- }
- }
- }
- return tdi_cxx_module_info;
- }
- Json::Value CollationInformationBmiInstallation(cmGeneratorTarget const* gt,
- std::string const& config)
- {
- cmInstallCxxModuleBmiGenerator const* bmi_gen = nullptr;
- for (auto const& ig : gt->Makefile->GetInstallGenerators()) {
- if (auto const* bmig =
- dynamic_cast<cmInstallCxxModuleBmiGenerator const*>(ig.get())) {
- if (bmig->GetTarget() == gt) {
- bmi_gen = bmig;
- continue;
- }
- }
- }
- if (bmi_gen) {
- Json::Value tdi_bmi_info = Json::objectValue;
- tdi_bmi_info["permissions"] = bmi_gen->GetFilePermissions();
- tdi_bmi_info["destination"] = bmi_gen->GetDestination(config);
- const char* msg_level = "";
- switch (bmi_gen->GetMessageLevel()) {
- case cmInstallGenerator::MessageDefault:
- break;
- case cmInstallGenerator::MessageAlways:
- msg_level = "MESSAGE_ALWAYS";
- break;
- case cmInstallGenerator::MessageLazy:
- msg_level = "MESSAGE_LAZY";
- break;
- case cmInstallGenerator::MessageNever:
- msg_level = "MESSAGE_NEVER";
- break;
- }
- tdi_bmi_info["message-level"] = msg_level;
- tdi_bmi_info["script-location"] = bmi_gen->GetScriptLocation(config);
- return tdi_bmi_info;
- }
- return Json::nullValue;
- }
- Json::Value CollationInformationExports(cmGeneratorTarget const* gt)
- {
- Json::Value tdi_exports = Json::arrayValue;
- std::string export_name = gt->GetExportName();
- std::string fs_export_name = gt->GetFilesystemExportName();
- auto const& all_install_exports = gt->GetGlobalGenerator()->GetExportSets();
- for (auto const& exp : all_install_exports) {
- // Ignore exports sets which are not for this target.
- auto const& targets = exp.second.GetTargetExports();
- auto tgt_export =
- std::find_if(targets.begin(), targets.end(),
- [gt](std::unique_ptr<cmTargetExport> const& te) {
- return te->Target == gt;
- });
- if (tgt_export == targets.end()) {
- continue;
- }
- auto const* installs = exp.second.GetInstallations();
- for (auto const* install : *installs) {
- Json::Value tdi_export_info = Json::objectValue;
- auto const& ns = install->GetNamespace();
- auto const& dest = install->GetDestination();
- auto const& cxxm_dir = install->GetCxxModuleDirectory();
- auto const& export_prefix = install->GetTempDir();
- tdi_export_info["namespace"] = ns;
- tdi_export_info["export-name"] = export_name;
- tdi_export_info["filesystem-export-name"] = fs_export_name;
- tdi_export_info["destination"] = dest;
- tdi_export_info["cxx-module-info-dir"] = cxxm_dir;
- tdi_export_info["export-prefix"] = export_prefix;
- tdi_export_info["install"] = true;
- tdi_exports.append(tdi_export_info);
- }
- }
- auto const& all_build_exports = gt->Makefile->GetExportBuildFileGenerators();
- for (auto const& exp : all_build_exports) {
- std::vector<std::string> targets;
- exp->GetTargets(targets);
- // Ignore exports sets which are not for this target.
- auto const& name = gt->GetName();
- bool has_current_target =
- std::any_of(targets.begin(), targets.end(),
- [name](std::string const& tname) { return tname == name; });
- if (!has_current_target) {
- continue;
- }
- Json::Value tdi_export_info = Json::objectValue;
- auto const& ns = exp->GetNamespace();
- auto const& main_fn = exp->GetMainExportFileName();
- auto const& cxxm_dir = exp->GetCxxModuleDirectory();
- auto dest = cmsys::SystemTools::GetParentDirectory(main_fn);
- auto const& export_prefix =
- cmSystemTools::GetFilenamePath(exp->GetMainExportFileName());
- tdi_export_info["namespace"] = ns;
- tdi_export_info["export-name"] = export_name;
- tdi_export_info["filesystem-export-name"] = fs_export_name;
- tdi_export_info["destination"] = dest;
- tdi_export_info["cxx-module-info-dir"] = cxxm_dir;
- tdi_export_info["export-prefix"] = export_prefix;
- tdi_export_info["install"] = false;
- tdi_exports.append(tdi_export_info);
- }
- return tdi_exports;
- }
- }
- void cmDyndepCollation::AddCollationInformation(
- Json::Value& tdi, cmGeneratorTarget const* gt, std::string const& config,
- cmDyndepGeneratorCallbacks const& cb)
- {
- tdi["cxx-modules"] = CollationInformationCxxModules(gt, config, cb);
- tdi["bmi-installation"] = CollationInformationBmiInstallation(gt, config);
- tdi["exports"] = CollationInformationExports(gt);
- tdi["config"] = config;
- }
- struct CxxModuleFileSet
- {
- std::string Name;
- bool BmiOnly = false;
- std::string RelativeDirectory;
- std::string SourcePath;
- std::string Type;
- cmFileSetVisibility Visibility = cmFileSetVisibility::Private;
- 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 FilesystemName;
- 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()) {
- export_info->Config = "noconfig";
- }
- Json::Value const& tdi_exports = tdi["exports"];
- if (tdi_exports.isArray()) {
- for (auto const& tdi_export : tdi_exports) {
- CxxModuleExport exp;
- exp.Install = tdi_export["install"].asBool();
- exp.Name = tdi_export["export-name"].asString();
- exp.FilesystemName = tdi_export["filesystem-export-name"].asString();
- exp.Destination = tdi_export["destination"].asString();
- exp.Prefix = tdi_export["export-prefix"].asString();
- exp.CxxModuleInfoDir = tdi_export["cxx-module-info-dir"].asString();
- exp.Namespace = tdi_export["namespace"].asString();
- export_info->Exports.push_back(exp);
- }
- }
- auto const& bmi_installation = tdi["bmi-installation"];
- if (bmi_installation.isObject()) {
- CxxModuleBmiInstall bmi_install;
- bmi_install.Component = bmi_installation["component"].asString();
- bmi_install.Destination = bmi_installation["destination"].asString();
- bmi_install.ExcludeFromAll = bmi_installation["exclude-from-all"].asBool();
- bmi_install.Optional = bmi_installation["optional"].asBool();
- bmi_install.Permissions = bmi_installation["permissions"].asString();
- bmi_install.MessageLevel = bmi_installation["message-level"].asString();
- bmi_install.ScriptLocation =
- bmi_installation["script-location"].asString();
- export_info->BmiInstallation = bmi_install;
- }
- Json::Value const& tdi_cxx_modules = tdi["cxx-modules"];
- if (tdi_cxx_modules.isObject()) {
- for (auto i = tdi_cxx_modules.begin(); i != tdi_cxx_modules.end(); ++i) {
- CxxModuleFileSet& fsi = export_info->ObjectToFileSet[i.key().asString()];
- auto const& tdi_cxx_module_info = *i;
- fsi.Name = tdi_cxx_module_info["name"].asString();
- fsi.BmiOnly = tdi_cxx_module_info["bmi-only"].asBool();
- fsi.RelativeDirectory =
- tdi_cxx_module_info["relative-directory"].asString();
- if (!fsi.RelativeDirectory.empty() &&
- fsi.RelativeDirectory.back() != '/') {
- fsi.RelativeDirectory = cmStrCat(fsi.RelativeDirectory, '/');
- }
- fsi.SourcePath = tdi_cxx_module_info["source"].asString();
- fsi.Type = tdi_cxx_module_info["type"].asString();
- fsi.Visibility = cmFileSetVisibilityFromName(
- tdi_cxx_module_info["visibility"].asString(), nullptr);
- auto const& tdi_fs_dest = tdi_cxx_module_info["destination"];
- if (tdi_fs_dest.isString()) {
- fsi.Destination = tdi_fs_dest.asString();
- }
- }
- }
- 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.FilesystemName, '-',
- 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 type `CXX_MODULES`
- // and be present.
- if (has_provides) {
- // Take the first module provided to provide context.
- auto const& provides = object.Provides[0];
- cmSystemTools::Error(
- cmStrCat("Output ", object.PrimaryOutput, " provides the `",
- provides.LogicalName,
- "` module but it is not found in a `FILE_SET` of type "
- "`CXX_MODULES`"));
- 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 "
- "interface unit or partition"));
- result = false;
- continue;
- }
- } else if (file_set.Type == "CXX_MODULE_HEADERS"_s) {
- // TODO.
- } else {
- if (has_provides) {
- auto const& provides = object.Provides[0];
- 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 `CXX_MODULES`"));
- 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;
- }
- bool cmDyndepCollation::IsObjectPrivate(
- std::string const& object, cmCxxModuleExportInfo const& export_info)
- {
- #ifdef _WIN32
- std::string output_path = object;
- cmSystemTools::ConvertToUnixSlashes(output_path);
- #else
- std::string const& output_path = object;
- #endif
- auto fileset_info_itr = export_info.ObjectToFileSet.find(output_path);
- if (fileset_info_itr == export_info.ObjectToFileSet.end()) {
- return false;
- }
- auto const& file_set = fileset_info_itr->second;
- return !cmFileSetVisibilityIsForInterface(file_set.Visibility);
- }
- bool cmDyndepCollation::IsBmiOnly(cmCxxModuleExportInfo const& exportInfo,
- std::string const& object)
- {
- #ifdef _WIN32
- auto object_path = object;
- cmSystemTools::ConvertToUnixSlashes(object_path);
- #else
- auto const& object_path = object;
- #endif
- auto fs = exportInfo.ObjectToFileSet.find(object_path);
- return (fs != exportInfo.ObjectToFileSet.end()) && fs->second.BmiOnly;
- }
|