cmake/Source/cmExportBuildFileGenerator.cxx

555 lines
19 KiB
C++
Raw Normal View History

2016-10-30 18:24:19 +01:00
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmExportBuildFileGenerator.h"
2022-05-25 20:56:39 +02:00
#include <algorithm>
2020-02-01 23:06:01 +01:00
#include <map>
#include <memory>
#include <set>
#include <sstream>
#include <utility>
2022-11-16 20:14:03 +01:00
#include <cm/string_view>
2020-08-30 11:54:41 +02:00
#include <cmext/algorithm>
2022-11-16 20:14:03 +01:00
#include <cmext/string_view>
2020-08-30 11:54:41 +02:00
2014-08-03 19:52:23 +02:00
#include "cmExportSet.h"
2022-03-29 21:10:50 +02:00
#include "cmFileSet.h"
2022-11-16 20:14:03 +01:00
#include "cmGeneratedFileStream.h"
2016-10-30 18:24:19 +01:00
#include "cmGeneratorExpression.h"
#include "cmGeneratorTarget.h"
2016-07-09 11:21:54 +02:00
#include "cmGlobalGenerator.h"
#include "cmLocalGenerator.h"
2016-10-30 18:24:19 +01:00
#include "cmMakefile.h"
2019-11-11 23:01:05 +01:00
#include "cmMessageType.h"
2022-03-29 21:10:50 +02:00
#include "cmOutputConverter.h"
2016-10-30 18:24:19 +01:00
#include "cmPolicies.h"
2017-04-14 19:02:05 +02:00
#include "cmStateTypes.h"
2020-02-01 23:06:01 +01:00
#include "cmStringAlgorithms.h"
2022-11-16 20:14:03 +01:00
#include "cmSystemTools.h"
2016-10-30 18:24:19 +01:00
#include "cmTarget.h"
2014-08-03 19:52:23 +02:00
#include "cmTargetExport.h"
2021-11-20 13:41:27 +01:00
#include "cmValue.h"
2016-10-30 18:24:19 +01:00
#include "cmake.h"
2017-07-20 19:35:53 +02:00
class cmSourceFile;
cmExportBuildFileGenerator::cmExportBuildFileGenerator()
{
2018-01-26 17:06:56 +01:00
this->LG = nullptr;
this->ExportSet = nullptr;
}
2016-03-13 13:35:51 +01:00
void cmExportBuildFileGenerator::Compute(cmLocalGenerator* lg)
{
this->LG = lg;
2016-07-09 11:21:54 +02:00
if (this->ExportSet) {
2016-03-13 13:35:51 +01:00
this->ExportSet->Compute(lg);
2016-07-09 11:21:54 +02:00
}
2016-03-13 13:35:51 +01:00
}
bool cmExportBuildFileGenerator::GenerateMainFile(std::ostream& os)
{
2013-03-16 19:13:01 +02:00
{
2016-07-09 11:21:54 +02:00
std::string expectedTargets;
std::string sep;
std::vector<std::string> targets;
2020-02-01 23:06:01 +01:00
bool generatedInterfaceRequired = false;
2016-07-09 11:21:54 +02:00
this->GetTargets(targets);
2018-01-26 17:06:56 +01:00
for (std::string const& tei : targets) {
cmGeneratorTarget* te = this->LG->FindGeneratorTargetToUse(tei);
2016-07-09 11:21:54 +02:00
expectedTargets += sep + this->Namespace + te->GetExportName();
sep = " ";
if (this->ExportedTargets.insert(te).second) {
this->Exports.push_back(te);
} else {
std::ostringstream e;
e << "given target \"" << te->GetName() << "\" more than once.";
this->LG->GetGlobalGenerator()->GetCMakeInstance()->IssueMessage(
2019-11-11 23:01:05 +01:00
MessageType::FATAL_ERROR, e.str(),
2016-07-09 11:21:54 +02:00
this->LG->GetMakefile()->GetBacktrace());
return false;
}
2020-02-01 23:06:01 +01:00
generatedInterfaceRequired |=
this->GetExportTargetType(te) == cmStateEnums::INTERFACE_LIBRARY;
}
2020-02-01 23:06:01 +01:00
if (generatedInterfaceRequired) {
this->GenerateRequiredCMakeVersion(os, "3.0.0");
}
2016-07-09 11:21:54 +02:00
this->GenerateExpectedTargetsCode(os, expectedTargets);
2013-03-16 19:13:01 +02:00
}
// Create all the imported targets.
2018-01-26 17:06:56 +01:00
for (cmGeneratorTarget* gte : this->Exports) {
2018-08-09 18:06:22 +02:00
this->GenerateImportTargetCode(os, gte, this->GetExportTargetType(gte));
2013-03-16 19:13:01 +02:00
2016-03-13 13:35:51 +01:00
gte->Target->AppendBuildInterfaceIncludes();
2013-03-16 19:13:01 +02:00
ImportPropertyMap properties;
2016-03-13 13:35:51 +01:00
this->PopulateInterfaceProperty("INTERFACE_INCLUDE_DIRECTORIES", gte,
2013-03-16 19:13:01 +02:00
cmGeneratorExpression::BuildInterface,
2022-08-04 22:12:04 +02:00
properties);
2016-03-13 13:35:51 +01:00
this->PopulateInterfaceProperty("INTERFACE_SOURCES", gte,
2015-08-17 11:37:30 +02:00
cmGeneratorExpression::BuildInterface,
2022-08-04 22:12:04 +02:00
properties);
2016-03-13 13:35:51 +01:00
this->PopulateInterfaceProperty("INTERFACE_COMPILE_DEFINITIONS", gte,
2013-03-16 19:13:01 +02:00
cmGeneratorExpression::BuildInterface,
2022-08-04 22:12:04 +02:00
properties);
2016-03-13 13:35:51 +01:00
this->PopulateInterfaceProperty("INTERFACE_COMPILE_OPTIONS", gte,
2013-11-03 12:27:13 +02:00
cmGeneratorExpression::BuildInterface,
2022-08-04 22:12:04 +02:00
properties);
2020-02-01 23:06:01 +01:00
this->PopulateInterfaceProperty("INTERFACE_PRECOMPILE_HEADERS", gte,
cmGeneratorExpression::BuildInterface,
2022-08-04 22:12:04 +02:00
properties);
2016-03-13 13:35:51 +01:00
this->PopulateInterfaceProperty("INTERFACE_AUTOUIC_OPTIONS", gte,
2014-08-03 19:52:23 +02:00
cmGeneratorExpression::BuildInterface,
2022-08-04 22:12:04 +02:00
properties);
2023-07-02 19:51:09 +02:00
this->PopulateInterfaceProperty("INTERFACE_AUTOMOC_MACRO_NAMES", gte,
cmGeneratorExpression::BuildInterface,
properties);
2016-03-13 13:35:51 +01:00
this->PopulateInterfaceProperty("INTERFACE_COMPILE_FEATURES", gte,
2015-04-27 22:25:09 +02:00
cmGeneratorExpression::BuildInterface,
2022-08-04 22:12:04 +02:00
properties);
2018-10-28 12:09:07 +01:00
this->PopulateInterfaceProperty("INTERFACE_LINK_OPTIONS", gte,
cmGeneratorExpression::BuildInterface,
2022-08-04 22:12:04 +02:00
properties);
2018-10-28 12:09:07 +01:00
this->PopulateInterfaceProperty("INTERFACE_LINK_DIRECTORIES", gte,
cmGeneratorExpression::BuildInterface,
2022-08-04 22:12:04 +02:00
properties);
2018-10-28 12:09:07 +01:00
this->PopulateInterfaceProperty("INTERFACE_LINK_DEPENDS", gte,
cmGeneratorExpression::BuildInterface,
2022-08-04 22:12:04 +02:00
properties);
2016-07-09 11:21:54 +02:00
this->PopulateInterfaceProperty("INTERFACE_POSITION_INDEPENDENT_CODE", gte,
properties);
2018-08-09 18:06:22 +02:00
std::string errorMessage;
if (!this->PopulateExportProperties(gte, properties, errorMessage)) {
this->LG->GetGlobalGenerator()->GetCMakeInstance()->IssueMessage(
2019-11-11 23:01:05 +01:00
MessageType::FATAL_ERROR, errorMessage,
2018-08-09 18:06:22 +02:00
this->LG->GetMakefile()->GetBacktrace());
return false;
}
2013-11-03 12:27:13 +02:00
const bool newCMP0022Behavior =
2016-07-09 11:21:54 +02:00
gte->GetPolicyStatusCMP0022() != cmPolicies::WARN &&
gte->GetPolicyStatusCMP0022() != cmPolicies::OLD;
if (newCMP0022Behavior) {
this->PopulateInterfaceLinkLibrariesProperty(
2022-08-04 22:12:04 +02:00
gte, cmGeneratorExpression::BuildInterface, properties);
2016-07-09 11:21:54 +02:00
}
2015-11-17 17:22:37 +01:00
this->PopulateCompatibleInterfaceProperties(gte, properties);
2013-03-16 19:13:01 +02:00
2016-03-13 13:35:51 +01:00
this->GenerateInterfaceProperties(gte, os, properties);
2022-03-29 21:10:50 +02:00
this->GenerateTargetFileSets(gte, os);
2016-07-09 11:21:54 +02:00
}
2013-03-16 19:13:01 +02:00
2022-11-16 20:14:03 +01:00
this->GenerateCxxModuleInformation(os);
// Generate import file content for each configuration.
2018-01-26 17:06:56 +01:00
for (std::string const& c : this->Configurations) {
2022-08-04 22:12:04 +02:00
this->GenerateImportConfig(os, c);
2016-07-09 11:21:54 +02:00
}
2022-11-16 20:14:03 +01:00
// Generate import file content for each configuration.
for (std::string const& c : this->Configurations) {
this->GenerateImportCxxModuleConfigTargetInclusion(c);
}
2022-08-04 22:12:04 +02:00
this->GenerateMissingTargetsCheckCode(os);
2013-03-16 19:13:01 +02:00
return true;
}
2016-07-09 11:21:54 +02:00
void cmExportBuildFileGenerator::GenerateImportTargetsConfig(
2022-08-04 22:12:04 +02:00
std::ostream& os, const std::string& config, std::string const& suffix)
{
2018-01-26 17:06:56 +01:00
for (cmGeneratorTarget* target : this->Exports) {
// Collect import properties for this target.
ImportPropertyMap properties;
2014-08-03 19:52:23 +02:00
2018-08-09 18:06:22 +02:00
if (this->GetExportTargetType(target) != cmStateEnums::INTERFACE_LIBRARY) {
2014-08-03 19:52:23 +02:00
this->SetImportLocationProperty(config, suffix, target, properties);
2016-07-09 11:21:54 +02:00
}
if (!properties.empty()) {
// Get the rest of the target details.
2018-08-09 18:06:22 +02:00
if (this->GetExportTargetType(target) !=
cmStateEnums::INTERFACE_LIBRARY) {
2022-08-04 22:12:04 +02:00
this->SetImportDetailProperties(config, suffix, target, properties);
2014-08-03 19:52:23 +02:00
this->SetImportLinkInterface(config, suffix,
2015-11-17 17:22:37 +01:00
cmGeneratorExpression::BuildInterface,
2022-08-04 22:12:04 +02:00
target, properties);
2016-07-09 11:21:54 +02:00
}
2018-08-09 18:06:22 +02:00
// TODO: PUBLIC_HEADER_LOCATION
// This should wait until the build feature propagation stuff
// is done. Then this can be a propagated include directory.
// this->GenerateImportProperty(config, te->HeaderGenerator,
// properties);
// Generate code in the export file.
2016-07-09 11:21:54 +02:00
this->GenerateImportPropertyCode(os, config, target, properties);
}
2016-07-09 11:21:54 +02:00
}
}
2018-08-09 18:06:22 +02:00
cmStateEnums::TargetType cmExportBuildFileGenerator::GetExportTargetType(
cmGeneratorTarget const* target) const
{
cmStateEnums::TargetType targetType = target->GetType();
// An object library exports as an interface library if we cannot
// tell clients where to find the objects. This is sufficient
// to support transitive usage requirements on other targets that
// use the object library.
if (targetType == cmStateEnums::OBJECT_LIBRARY &&
2022-08-04 22:12:04 +02:00
!target->Target->HasKnownObjectFileLocation(nullptr)) {
2018-08-09 18:06:22 +02:00
targetType = cmStateEnums::INTERFACE_LIBRARY;
}
return targetType;
}
2016-07-09 11:21:54 +02:00
void cmExportBuildFileGenerator::SetExportSet(cmExportSet* exportSet)
2014-08-03 19:52:23 +02:00
{
this->ExportSet = exportSet;
}
2016-07-09 11:21:54 +02:00
void cmExportBuildFileGenerator::SetImportLocationProperty(
const std::string& config, std::string const& suffix,
cmGeneratorTarget* target, ImportPropertyMap& properties)
{
// Get the makefile in which to lookup target information.
2015-11-17 17:22:37 +01:00
cmMakefile* mf = target->Makefile;
2017-07-20 19:35:53 +02:00
if (target->GetType() == cmStateEnums::OBJECT_LIBRARY) {
2020-02-01 23:06:01 +01:00
std::string prop = cmStrCat("IMPORTED_OBJECTS", suffix);
2017-07-20 19:35:53 +02:00
// Compute all the object files inside this target and setup
// IMPORTED_OBJECTS as a list of object files
std::vector<cmSourceFile const*> objectSources;
target->GetObjectSources(objectSources, config);
std::string const obj_dir = target->GetObjectDirectory(config);
std::vector<std::string> objects;
2018-01-26 17:06:56 +01:00
for (cmSourceFile const* sf : objectSources) {
const std::string& obj = target->GetObjectName(sf);
2017-07-20 19:35:53 +02:00
objects.push_back(obj_dir + obj);
}
2017-07-20 19:35:53 +02:00
// Store the property.
properties[prop] = cmJoin(objects, ";");
} else {
// Add the main target file.
{
2020-02-01 23:06:01 +01:00
std::string prop = cmStrCat("IMPORTED_LOCATION", suffix);
2017-07-20 19:35:53 +02:00
std::string value;
if (target->IsAppBundleOnApple()) {
value =
target->GetFullPath(config, cmStateEnums::RuntimeBinaryArtifact);
} else {
value = target->GetFullPath(config,
cmStateEnums::RuntimeBinaryArtifact, true);
}
properties[prop] = value;
}
// Add the import library for windows DLLs.
2020-02-01 23:06:01 +01:00
if (target->HasImportLibrary(config)) {
std::string prop = cmStrCat("IMPORTED_IMPLIB", suffix);
2017-07-20 19:35:53 +02:00
std::string value =
2023-07-02 19:51:09 +02:00
target->GetFullPath(config, cmStateEnums::ImportLibraryArtifact, true);
2020-02-01 23:06:01 +01:00
if (mf->GetDefinition("CMAKE_IMPORT_LIBRARY_SUFFIX")) {
target->GetImplibGNUtoMS(config, value, value,
"${CMAKE_IMPORT_LIBRARY_SUFFIX}");
}
2017-07-20 19:35:53 +02:00
properties[prop] = value;
}
2016-07-09 11:21:54 +02:00
}
}
2016-07-09 11:21:54 +02:00
void cmExportBuildFileGenerator::HandleMissingTarget(
2022-08-04 22:12:04 +02:00
std::string& link_libs, cmGeneratorTarget const* depender,
cmGeneratorTarget* dependee)
2013-03-16 19:13:01 +02:00
{
// The target is not in the export.
2016-07-09 11:21:54 +02:00
if (!this->AppendMode) {
2014-08-03 19:52:23 +02:00
const std::string name = dependee->GetName();
2016-03-13 13:35:51 +01:00
cmGlobalGenerator* gg =
2016-07-09 11:21:54 +02:00
dependee->GetLocalGenerator()->GetGlobalGenerator();
2020-02-01 23:06:01 +01:00
auto exportInfo = this->FindBuildExportInfo(gg, name);
std::vector<std::string> const& exportFiles = exportInfo.first;
2014-08-03 19:52:23 +02:00
2020-02-01 23:06:01 +01:00
if (exportFiles.size() == 1) {
std::string missingTarget = exportInfo.second;
2014-08-03 19:52:23 +02:00
missingTarget += dependee->GetExportName();
link_libs += missingTarget;
2022-08-04 22:12:04 +02:00
this->MissingTargets.emplace_back(std::move(missingTarget));
2014-08-03 19:52:23 +02:00
return;
2013-03-16 19:13:01 +02:00
}
2016-10-30 18:24:19 +01:00
// We are not appending, so all exported targets should be
// known here. This is probably user-error.
2020-02-01 23:06:01 +01:00
this->ComplainAboutMissingTarget(depender, dependee, exportFiles);
2016-07-09 11:21:54 +02:00
}
2013-03-16 19:13:01 +02:00
// Assume the target will be exported by another command.
// Append it with the export namespace.
link_libs += this->Namespace;
2013-11-03 12:27:13 +02:00
link_libs += dependee->GetExportName();
2013-03-16 19:13:01 +02:00
}
2016-07-09 11:21:54 +02:00
void cmExportBuildFileGenerator::GetTargets(
std::vector<std::string>& targets) const
2014-08-03 19:52:23 +02:00
{
2016-07-09 11:21:54 +02:00
if (this->ExportSet) {
2020-02-01 23:06:01 +01:00
for (std::unique_ptr<cmTargetExport> const& te :
this->ExportSet->GetTargetExports()) {
2021-09-14 00:13:48 +02:00
if (te->NamelinkOnly) {
continue;
}
2018-01-26 17:06:56 +01:00
targets.push_back(te->TargetName);
2014-08-03 19:52:23 +02:00
}
2016-07-09 11:21:54 +02:00
return;
}
2014-08-03 19:52:23 +02:00
targets = this->Targets;
}
2020-02-01 23:06:01 +01:00
std::pair<std::vector<std::string>, std::string>
cmExportBuildFileGenerator::FindBuildExportInfo(cmGlobalGenerator* gg,
const std::string& name)
2014-08-03 19:52:23 +02:00
{
2020-02-01 23:06:01 +01:00
std::vector<std::string> exportFiles;
std::string ns;
2014-08-03 19:52:23 +02:00
2020-08-30 11:54:41 +02:00
auto& exportSets = gg->GetBuildExportSets();
2014-08-03 19:52:23 +02:00
2018-01-26 17:06:56 +01:00
for (auto const& exp : exportSets) {
2020-08-30 11:54:41 +02:00
const auto& exportSet = exp.second;
2014-08-03 19:52:23 +02:00
std::vector<std::string> targets;
exportSet->GetTargets(targets);
2020-08-30 11:54:41 +02:00
if (cm::contains(targets, name)) {
2020-02-01 23:06:01 +01:00
exportFiles.push_back(exp.first);
ns = exportSet->GetNamespace();
2014-08-03 19:52:23 +02:00
}
2016-07-09 11:21:54 +02:00
}
2014-08-03 19:52:23 +02:00
2020-02-01 23:06:01 +01:00
return { exportFiles, ns };
2014-08-03 19:52:23 +02:00
}
2016-07-09 11:21:54 +02:00
void cmExportBuildFileGenerator::ComplainAboutMissingTarget(
2021-11-20 13:41:27 +01:00
cmGeneratorTarget const* depender, cmGeneratorTarget const* dependee,
2020-02-01 23:06:01 +01:00
std::vector<std::string> const& exportFiles)
{
2015-04-27 22:25:09 +02:00
std::ostringstream e;
2014-08-03 19:52:23 +02:00
e << "export called with target \"" << depender->GetName()
<< "\" which requires target \"" << dependee->GetName() << "\" ";
2020-02-01 23:06:01 +01:00
if (exportFiles.empty()) {
e << "that is not in any export set.";
2016-07-09 11:21:54 +02:00
} else {
2020-02-01 23:06:01 +01:00
e << "that is not in this export set, but in multiple other export sets: "
<< cmJoin(exportFiles, ", ") << ".\n";
e << "An exported target cannot depend upon another target which is "
"exported multiple times. Consider consolidating the exports of the "
"\""
<< dependee->GetName() << "\" target to a single export.";
2016-07-09 11:21:54 +02:00
}
2014-08-03 19:52:23 +02:00
2016-07-09 11:21:54 +02:00
this->LG->GetGlobalGenerator()->GetCMakeInstance()->IssueMessage(
2019-11-11 23:01:05 +01:00
MessageType::FATAL_ERROR, e.str(),
this->LG->GetMakefile()->GetBacktrace());
}
2013-11-03 12:27:13 +02:00
2016-07-09 11:21:54 +02:00
std::string cmExportBuildFileGenerator::InstallNameDir(
2021-11-20 13:41:27 +01:00
cmGeneratorTarget const* target, const std::string& config)
2013-11-03 12:27:13 +02:00
{
std::string install_name_dir;
2015-11-17 17:22:37 +01:00
cmMakefile* mf = target->Target->GetMakefile();
2016-07-09 11:21:54 +02:00
if (mf->IsOn("CMAKE_PLATFORM_HAS_INSTALLNAME")) {
install_name_dir = target->GetInstallNameDirForBuildTree(config);
}
2013-11-03 12:27:13 +02:00
return install_name_dir;
}
2022-03-29 21:10:50 +02:00
2022-05-25 20:56:39 +02:00
namespace {
bool EntryIsContextSensitive(
const std::unique_ptr<cmCompiledGeneratorExpression>& cge)
{
return cge->GetHadContextSensitiveCondition();
}
}
2022-03-29 21:10:50 +02:00
std::string cmExportBuildFileGenerator::GetFileSetDirectories(
2022-05-25 20:56:39 +02:00
cmGeneratorTarget* gte, cmFileSet* fileSet, cmTargetExport* /*te*/)
2022-03-29 21:10:50 +02:00
{
2022-05-25 20:56:39 +02:00
std::vector<std::string> resultVector;
auto configs =
gte->Makefile->GetGeneratorConfigs(cmMakefile::IncludeEmptyConfig);
auto directoryEntries = fileSet->CompileDirectoryEntries();
for (auto const& config : configs) {
auto directories = fileSet->EvaluateDirectoryEntries(
directoryEntries, gte->LocalGenerator, config, gte);
bool const contextSensitive =
std::any_of(directoryEntries.begin(), directoryEntries.end(),
EntryIsContextSensitive);
2022-11-16 20:14:03 +01:00
auto const& type = fileSet->GetType();
// C++ modules do not support interface file sets which are dependent upon
// the configuration.
2023-07-02 19:51:09 +02:00
if (contextSensitive && type == "CXX_MODULES"_s) {
2022-11-16 20:14:03 +01:00
auto* mf = this->LG->GetMakefile();
std::ostringstream e;
e << "The \"" << gte->GetName() << "\" target's interface file set \""
<< fileSet->GetName() << "\" of type \"" << type
<< "\" contains context-sensitive base directory entries which is not "
"supported.";
mf->IssueMessage(MessageType::FATAL_ERROR, e.str());
return std::string{};
}
2022-05-25 20:56:39 +02:00
for (auto const& directory : directories) {
auto dest = cmOutputConverter::EscapeForCMake(
directory, cmOutputConverter::WrapQuotes::NoWrap);
if (contextSensitive && configs.size() != 1) {
resultVector.push_back(
cmStrCat("\"$<$<CONFIG:", config, ">:", dest, ">\""));
} else {
resultVector.push_back(cmStrCat('"', dest, '"'));
break;
}
}
}
return cmJoin(resultVector, " ");
2022-03-29 21:10:50 +02:00
}
2022-05-25 20:56:39 +02:00
std::string cmExportBuildFileGenerator::GetFileSetFiles(cmGeneratorTarget* gte,
cmFileSet* fileSet,
cmTargetExport* /*te*/)
2022-03-29 21:10:50 +02:00
{
2022-05-25 20:56:39 +02:00
std::vector<std::string> resultVector;
auto configs =
gte->Makefile->GetGeneratorConfigs(cmMakefile::IncludeEmptyConfig);
auto fileEntries = fileSet->CompileFileEntries();
auto directoryEntries = fileSet->CompileDirectoryEntries();
for (auto const& config : configs) {
auto directories = fileSet->EvaluateDirectoryEntries(
directoryEntries, gte->LocalGenerator, config, gte);
std::map<std::string, std::vector<std::string>> files;
for (auto const& entry : fileEntries) {
fileSet->EvaluateFileEntry(directories, files, entry,
gte->LocalGenerator, config, gte);
}
bool const contextSensitive =
std::any_of(directoryEntries.begin(), directoryEntries.end(),
EntryIsContextSensitive) ||
std::any_of(fileEntries.begin(), fileEntries.end(),
EntryIsContextSensitive);
2022-11-16 20:14:03 +01:00
auto const& type = fileSet->GetType();
// C++ modules do not support interface file sets which are dependent upon
// the configuration.
2023-07-02 19:51:09 +02:00
if (contextSensitive && type == "CXX_MODULES"_s) {
2022-11-16 20:14:03 +01:00
auto* mf = this->LG->GetMakefile();
std::ostringstream e;
e << "The \"" << gte->GetName() << "\" target's interface file set \""
<< fileSet->GetName() << "\" of type \"" << type
<< "\" contains context-sensitive file entries which is not "
"supported.";
mf->IssueMessage(MessageType::FATAL_ERROR, e.str());
return std::string{};
}
2022-05-25 20:56:39 +02:00
for (auto const& it : files) {
for (auto const& filename : it.second) {
auto escapedFile = cmOutputConverter::EscapeForCMake(
filename, cmOutputConverter::WrapQuotes::NoWrap);
if (contextSensitive && configs.size() != 1) {
resultVector.push_back(
cmStrCat("\"$<$<CONFIG:", config, ">:", escapedFile, ">\""));
} else {
resultVector.push_back(cmStrCat('"', escapedFile, '"'));
}
}
}
if (!(contextSensitive && configs.size() != 1)) {
break;
}
}
return cmJoin(resultVector, " ");
2022-03-29 21:10:50 +02:00
}
2022-11-16 20:14:03 +01:00
std::string cmExportBuildFileGenerator::GetCxxModulesDirectory() const
{
return this->CxxModulesDirectory;
}
void cmExportBuildFileGenerator::GenerateCxxModuleConfigInformation(
std::ostream& os) const
{
const char* opt = "";
if (this->Configurations.size() > 1) {
// With more than one configuration, each individual file is optional.
opt = " OPTIONAL";
}
// Generate import file content for each configuration.
for (std::string c : this->Configurations) {
if (c.empty()) {
c = "noconfig";
}
os << "include(\"${CMAKE_CURRENT_LIST_DIR}/cxx-modules-" << c << ".cmake\""
<< opt << ")\n";
}
}
bool cmExportBuildFileGenerator::GenerateImportCxxModuleConfigTargetInclusion(
std::string config) const
{
auto cxx_modules_dirname = this->GetCxxModulesDirectory();
if (cxx_modules_dirname.empty()) {
return true;
}
if (config.empty()) {
config = "noconfig";
}
std::string fileName = cmStrCat(this->FileDir, '/', cxx_modules_dirname,
"/cxx-modules-", 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);
for (auto const* tgt : this->ExportedTargets) {
2023-07-02 19:51:09 +02:00
// Only targets with C++ module sources will have a
// collator-generated install script.
if (!tgt->HaveCxx20ModuleSources()) {
continue;
}
2022-11-16 20:14:03 +01:00
os << "include(\"${CMAKE_CURRENT_LIST_DIR}/target-" << tgt->GetExportName()
<< '-' << config << ".cmake\")\n";
}
return true;
}