cmFileSet: Enhance type management

Type management is now dynamic to ensure future support of user's types.
This commit is contained in:
Marc Chevrier committed 2026-02-19 17:03:45 +01:00
1 parent 54e1cb0c58
commit c4c84ae0f7
24 files changed
+234 -217

No files matched your search

+2 -2
View File
@@ -449,9 +449,9 @@ cmBuildDatabase cmBuildDatabase::ForTarget(cmGeneratorTarget* gt,
bool isPrivate = true;
if (sf->GetLanguage() == "CXX"_s) {
auto const* fs = gt->GetFileSetForSource(config, sf);
if (fs && fs->GetType() == "CXX_MODULES"_s) {
if (fs && fs->GetType() == cmFileSet::CXX_MODULES) {
isCXXModule = true;
isPrivate = !cmFileSetVisibilityIsForInterface(fs->GetVisibility());
isPrivate = !cmFileSet::VisibilityIsForInterface(fs->GetVisibility());
}
}
+3 -2
View File
@@ -448,8 +448,9 @@ void cmCxxModuleMetadata::PopulateTarget(
std::string metadataDir =
cmSystemTools::GetFilenamePath(meta.MetadataFilePath);
auto fileSet = target.GetOrCreateFileSet("CXX_MODULES", "CXX_MODULES",
cmFileSetVisibility::Interface);
auto fileSet = target.GetOrCreateFileSet(
std::string{ cmFileSet::CXX_MODULES },
std::string{ cmFileSet::CXX_MODULES }, cmFileSet::Visibility::Interface);
for (auto const& module : meta.Modules) {
std::string sourcePath = module.SourcePath;
+7 -7
View File
@@ -195,13 +195,13 @@ std::shared_ptr<cmDebuggerVariables> cmDebuggerVariablesHelper::CreateIfAny(
return {};
}
static auto visibilityString = [](cmFileSetVisibility visibility) {
static auto visibilityString = [](cmFileSet::Visibility visibility) {
switch (visibility) {
case cmFileSetVisibility::Private:
case cmFileSet::Visibility::Private:
return "Private";
case cmFileSetVisibility::Public:
case cmFileSet::Visibility::Public:
return "Public";
case cmFileSetVisibility::Interface:
case cmFileSet::Visibility::Interface:
return "Interface";
default:
return "Unknown";
@@ -307,13 +307,13 @@ std::shared_ptr<cmDebuggerVariables> cmDebuggerVariablesHelper::CreateIfAny(
target->GetCompileOptionsEntries()));
targetVariables->AddSubVariables(
CreateIfAny(variablesManager, "CxxModuleSets", supportsVariableType,
target->GetCxxModuleSetsEntries()));
target->GetFileSetsEntries(cmFileSet::CXX_MODULES)));
targetVariables->AddSubVariables(
CreateIfAny(variablesManager, "HeaderSets", supportsVariableType,
target->GetHeaderSetsEntries()));
target->GetFileSetsEntries(cmFileSet::HEADERS)));
targetVariables->AddSubVariables(CreateIfAny(
variablesManager, "InterfaceHeaderSets", supportsVariableType,
target->GetInterfaceHeaderSetsEntries()));
target->GetInterfaceFileSetsEntries(cmFileSet::HEADERS)));
targetVariables->AddSubVariables(
CreateIfAny(variablesManager, "LinkDirectories", supportsVariableType,
target->GetLinkDirectoriesEntries()));
+20 -20
View File
@@ -105,12 +105,12 @@ TdiSourceInfo CollationInformationSources(cmGeneratorTarget const* gt,
}
auto fs_type = file_set->GetType();
// We only care about C++ module sources here.
if (fs_type != "CXX_MODULES"_s) {
if (fs_type != cmFileSet::CXX_MODULES) {
continue;
}
// Synthetic (BMI-only) targets do not build private C++ modules.
if (tgt->IsSynthetic() &&
file_set->GetVisibility() == cmFileSetVisibility::Private) {
file_set->GetVisibility() == cmFileSet::Visibility::Private) {
continue;
}
@@ -148,16 +148,16 @@ TdiSourceInfo CollationInformationSources(cmGeneratorTarget const* gt,
// Duplicate source; raise an author warning.
gt->Makefile->IssueMessage(
MessageType::AUTHOR_WARNING,
cmStrCat(
"Target \"", tgt->GetName(), "\" has source file\n ", file,
"\nin a \"FILE_SET TYPE CXX_MODULES\" multiple times."));
cmStrCat("Target \"", tgt->GetName(), "\" has source file\n ",
file, "\nin a \"FILE_SET TYPE ", cmFileSet::CXX_MODULES,
"\" multiple times."));
continue;
}
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 "
file, "\nin a \"FILE_SET TYPE ", cmFileSet::CXX_MODULES,
"\" but it is not "
"scheduled for compilation."));
continue;
}
@@ -212,7 +212,7 @@ TdiSourceInfo CollationInformationSources(cmGeneratorTarget const* gt,
tdi_module_info["name"] = file_set->GetName();
tdi_module_info["type"] = file_set->GetType();
tdi_module_info["visibility"] =
std::string(cmFileSetVisibilityToName(file_set->GetVisibility()));
std::string(cmFileSet::VisibilityToName(file_set->GetVisibility()));
tdi_module_info["destination"] = fs_dest;
}
}
@@ -403,7 +403,7 @@ struct CxxModuleFileSet
std::string RelativeDirectory;
std::string SourcePath;
std::string Type;
cmFileSetVisibility Visibility = cmFileSetVisibility::Private;
cmFileSet::Visibility Visibility = cmFileSet::Visibility::Private;
cm::optional<std::string> Destination;
std::vector<std::string> IncludeDirectories;
std::vector<std::string> Definitions;
@@ -526,7 +526,7 @@ cmDyndepCollation::ParseExportInfo(Json::Value const& tdi)
}
fsi.SourcePath = tdi_cxx_module_info["source"].asString();
fsi.Type = tdi_cxx_module_info["type"].asString();
fsi.Visibility = cmFileSetVisibilityFromName(
fsi.Visibility = cmFileSet::VisibilityFromName(
tdi_cxx_module_info["visibility"].asString(), nullptr);
auto const& tdi_fs_dest = tdi_cxx_module_info["destination"];
if (tdi_fs_dest.isString()) {
@@ -676,8 +676,8 @@ bool cmDyndepCollation::WriteDyndepMetadata(
cmSystemTools::Error(
cmStrCat("Output ", object.PrimaryOutput, " provides the `",
provides.LogicalName,
"` module but it is not found in a `FILE_SET` of type "
"`CXX_MODULES`"));
"` module but it is not found in a `FILE_SET` of type `",
cmFileSet::CXX_MODULES, '`'));
result = false;
}
@@ -717,12 +717,12 @@ bool cmDyndepCollation::WriteDyndepMetadata(
}
// Verify the fileset type for the object.
if (file_set.Type == "CXX_MODULES"_s) {
if (file_set.Type == cmFileSet::CXX_MODULES) {
if (!has_provides) {
cmSystemTools::Error(
cmStrCat("Output ", object.PrimaryOutput,
" is of type `CXX_MODULES` but does not provide a module "
"interface unit or partition"));
cmSystemTools::Error(cmStrCat("Output ", object.PrimaryOutput,
" is of type `", cmFileSet::CXX_MODULES,
"` but does not provide a module "
"interface unit or partition"));
result = false;
continue;
}
@@ -734,7 +734,7 @@ bool cmDyndepCollation::WriteDyndepMetadata(
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`"));
"` module but must be of type `", cmFileSet::CXX_MODULES, '`'));
result = false;
}
@@ -742,7 +742,7 @@ bool cmDyndepCollation::WriteDyndepMetadata(
continue;
}
if (!cmFileSetVisibilityIsForInterface(file_set.Visibility)) {
if (!cmFileSet::VisibilityIsForInterface(file_set.Visibility)) {
// Nothing needs to be conveyed about non-`PUBLIC` modules.
for (auto const& p : object.Provides) {
private_modules.insert(p.LogicalName);
@@ -926,7 +926,7 @@ bool cmDyndepCollation::IsObjectPrivate(
return false;
}
auto const& file_set = fileset_info_itr->second;
return !cmFileSetVisibilityIsForInterface(file_set.Visibility);
return !cmFileSet::VisibilityIsForInterface(file_set.Visibility);
}
bool cmDyndepCollation::IsBmiOnly(cmCxxModuleExportInfo const& exportInfo,
+2 -2
View File
@@ -189,7 +189,7 @@ std::string cmExportBuildCMakeConfigGenerator::GetFileSetDirectories(
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) {
if (contextSensitive && type == cmFileSet::CXX_MODULES) {
auto* mf = this->LG->GetMakefile();
std::ostringstream e;
e << "The \"" << gte->GetName() << "\" target's interface file set \""
@@ -246,7 +246,7 @@ std::string cmExportBuildCMakeConfigGenerator::GetFileSetFiles(
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) {
if (contextSensitive && type == cmFileSet::CXX_MODULES) {
auto* mf = this->LG->GetMakefile();
std::ostringstream e;
e << "The \"" << gte->GetName() << "\" target's interface file set \""
+1 -1
View File
@@ -639,7 +639,7 @@ void cmExportCMakeConfigGenerator::GenerateTargetFileSets(
return;
}
if (fileSet->GetType() == "HEADERS"_s) {
if (fileSet->GetType() == cmFileSet::HEADERS) {
os << "\n " << this->GetFileSetDirectories(gte, fileSet, te);
}
}
@@ -302,7 +302,8 @@ std::string cmExportInstallCMakeConfigGenerator::GetFileSetDirectories(
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) {
if (cge->GetHadContextSensitiveCondition() &&
type == cmFileSet::CXX_MODULES) {
auto* mf = this->IEGen->GetLocalGenerator()->GetMakefile();
std::ostringstream e;
e << "The \"" << gte->GetName() << "\" target's interface file set \""
@@ -367,7 +368,7 @@ std::string cmExportInstallCMakeConfigGenerator::GetFileSetFiles(
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) {
if (contextSensitive && type == cmFileSet::CXX_MODULES) {
auto* mf = this->IEGen->GetLocalGenerator()->GetMakefile();
std::ostringstream e;
e << "The \"" << gte->GetName() << "\" target's interface file set \""
@@ -240,7 +240,7 @@ cmExportInstallPackageInfoGenerator::GetFileSetDirectory(
}
std::string const& type = fileSet->GetType();
if (config && (type == "CXX_MODULES"_s)) {
if (config && (type == cmFileSet::CXX_MODULES)) {
// C++ modules do not support interface file sets which are dependent
// upon the configuration.
cmMakefile* mf = gte->LocalGenerator->GetMakefile();
@@ -284,13 +284,13 @@ bool cmExportInstallPackageInfoGenerator::GenerateFileSetProperties(
cm::optional<std::string> const& fileSetDirectory =
this->GetFileSetDirectory(gte, te, fileSet, config);
if (fileSet->GetType() == "HEADERS"_s) {
if (fileSet->GetType() == cmFileSet::HEADERS) {
if (fileSetDirectory &&
!cm::contains(seenIncludeDirectories, *fileSetDirectory)) {
component["includes"].append(*fileSetDirectory);
seenIncludeDirectories.insert(*fileSetDirectory);
}
} else if (fileSet->GetType() == "CXX_MODULES"_s) {
} else if (fileSet->GetType() == cmFileSet::CXX_MODULES) {
hasModules = true;
this->RequiresConfigFiles = true;
}
+1 -1
View File
@@ -228,7 +228,7 @@ cm::optional<std::string> cmExportInstallSbomGenerator::GetFileSetDirectory(
}
std::string const& type = fileSet->GetType();
if (config && (type == "CXX_MODULES"_s)) {
if (config && (type == cmFileSet::CXX_MODULES)) {
cmMakefile* mf = gte->LocalGenerator->GetMakefile();
std::ostringstream e;
e << "The \"" << gte->GetName() << "\" target's interface file set \""
+3 -3
View File
@@ -465,7 +465,7 @@ class Target
using FileSetDatabase = std::map<std::string, Json::ArrayIndex>;
std::vector<cmFileSetVisibility> FileSetVisibilities;
std::vector<cmFileSet::Visibility> FileSetVisibilities;
template <typename T>
JBT<T> ToJBT(BT<T> const& bt)
@@ -1788,7 +1788,7 @@ Json::Value Target::DumpFileSet(cmFileSet const* fs,
fileSet["name"] = fs->GetName();
fileSet["type"] = fs->GetType();
fileSet["visibility"] =
std::string(cmFileSetVisibilityToName(fs->GetVisibility()));
std::string(cmFileSet::VisibilityToName(fs->GetVisibility()));
Json::Value baseDirs = Json::arrayValue;
for (auto const& directory : directories) {
@@ -1888,7 +1888,7 @@ Json::Value Target::DumpInterfaceSources(FileSetDatabase const& fsdb)
Json::ArrayIndex const index = fsIter.second;
// FileSetVisibilities was populated by DumpFileSets() and will always
// have the same size as the file sets array that index is indexing into
if (this->FileSetVisibilities[index] != cmFileSetVisibility::Private) {
if (this->FileSetVisibilities[index] != cmFileSet::Visibility::Private) {
dumpFile(fsIter.first);
}
}
+37 -22
View File
@@ -25,30 +25,30 @@
#include "cmSystemTools.h"
#include "cmake.h"
cm::static_string_view cmFileSetVisibilityToName(cmFileSetVisibility vis)
cm::static_string_view cmFileSet::VisibilityToName(Visibility vis)
{
switch (vis) {
case cmFileSetVisibility::Interface:
case Visibility::Interface:
return "INTERFACE"_s;
case cmFileSetVisibility::Public:
case Visibility::Public:
return "PUBLIC"_s;
case cmFileSetVisibility::Private:
case Visibility::Private:
return "PRIVATE"_s;
}
return ""_s;
}
cmFileSetVisibility cmFileSetVisibilityFromName(cm::string_view name,
cmMakefile* mf)
cmFileSet::Visibility cmFileSet::VisibilityFromName(cm::string_view name,
cmMakefile* mf)
{
if (name == "INTERFACE"_s) {
return cmFileSetVisibility::Interface;
return Visibility::Interface;
}
if (name == "PUBLIC"_s) {
return cmFileSetVisibility::Public;
return Visibility::Public;
}
if (name == "PRIVATE"_s) {
return cmFileSetVisibility::Private;
return Visibility::Private;
}
auto msg = cmStrCat("File set visibility \"", name, "\" is not valid.");
if (mf) {
@@ -56,44 +56,59 @@ cmFileSetVisibility cmFileSetVisibilityFromName(cm::string_view name,
} else {
cmSystemTools::Error(msg);
}
return cmFileSetVisibility::Private;
return Visibility::Private;
}
bool cmFileSetVisibilityIsForSelf(cmFileSetVisibility vis)
bool cmFileSet::VisibilityIsForSelf(Visibility vis)
{
switch (vis) {
case cmFileSetVisibility::Interface:
case Visibility::Interface:
return false;
case cmFileSetVisibility::Public:
case cmFileSetVisibility::Private:
case Visibility::Public:
case Visibility::Private:
return true;
}
return false;
}
bool cmFileSetVisibilityIsForInterface(cmFileSetVisibility vis)
bool cmFileSet::VisibilityIsForInterface(Visibility vis)
{
switch (vis) {
case cmFileSetVisibility::Interface:
case cmFileSetVisibility::Public:
case Visibility::Interface:
case Visibility::Public:
return true;
case cmFileSetVisibility::Private:
case Visibility::Private:
return false;
}
return false;
}
cm::static_string_view const cmFileSet::HEADERS = "HEADERS"_s;
cm::static_string_view const cmFileSet::CXX_MODULES = "CXX_MODULES"_s;
bool cmFileSetTypeCanBeIncluded(std::string const& type)
bool cmFileSet::IsKnownType(std::string const& type)
{
return type == "HEADERS"_s;
return cm::contains(GetKnownTypes(), type);
}
bool cmFileSet::TypeCanBeIncluded(std::string const& type)
{
return type == HEADERS;
}
cmList const& cmFileSet::GetKnownTypes()
{
return KnownTypes;
}
cmList cmFileSet::KnownTypes{ std::string{ HEADERS },
std::string{ CXX_MODULES } };
cmFileSet::cmFileSet(cmMakefile* makefile, std::string name, std::string type,
cmFileSetVisibility visibility)
Visibility visibility)
: Makefile(makefile)
, Name(std::move(name))
, Type(std::move(type))
, Visibility(visibility)
, FSVisibility(visibility)
{
}
+27 -17
View File
@@ -11,6 +11,7 @@
#include <cm/string_view>
#include <cmext/string_view>
#include "cmList.h"
#include "cmListFileCache.h"
#include "cmPropertyMap.h"
#include "cmValue.h"
@@ -26,29 +27,36 @@ struct cmGeneratorExpressionDAGChecker;
class cmGeneratorTarget;
class cmMakefile;
enum class cmFileSetVisibility
{
Private,
Public,
Interface,
};
cm::static_string_view cmFileSetVisibilityToName(cmFileSetVisibility vis);
cmFileSetVisibility cmFileSetVisibilityFromName(cm::string_view name,
cmMakefile* mf);
bool cmFileSetVisibilityIsForSelf(cmFileSetVisibility vis);
bool cmFileSetVisibilityIsForInterface(cmFileSetVisibility vis);
bool cmFileSetTypeCanBeIncluded(std::string const& type);
class cmFileSet
{
public:
enum class Visibility
{
Private,
Public,
Interface,
};
static cm::static_string_view VisibilityToName(Visibility vis);
static Visibility VisibilityFromName(cm::string_view name, cmMakefile* mf);
static bool VisibilityIsForSelf(Visibility vis);
static bool VisibilityIsForInterface(Visibility vis);
static bool IsKnownType(std::string const& type);
static bool TypeCanBeIncluded(std::string const& type);
// Pre-defined FileSet types
static cm::static_string_view const HEADERS;
static cm::static_string_view const CXX_MODULES;
static cmList const& GetKnownTypes();
cmFileSet(cmMakefile* makefile, std::string name, std::string type,
cmFileSetVisibility visibility);
Visibility visibility);
std::string const& GetName() const { return this->Name; }
std::string const& GetType() const { return this->Type; }
cmFileSetVisibility GetVisibility() const { return this->Visibility; }
Visibility GetVisibility() const { return this->FSVisibility; }
cmMakefile* GetMakefile() const { return this->Makefile; }
@@ -107,10 +115,12 @@ public:
cmValue GetProperty(std::string const& prop) const;
private:
static cmList KnownTypes;
cmMakefile* Makefile;
std::string Name;
std::string Type;
cmFileSetVisibility Visibility;
Visibility FSVisibility;
std::vector<BT<std::string>> DirectoryEntries;
std::vector<BT<std::string>> FileEntries;
cmPropertyMap Properties;
+7 -7
View File
@@ -1122,8 +1122,8 @@ bool cmGeneratorTarget::IsInBuildSystem() const
// An INTERFACE library is in the build system if it has SOURCES
// or C++ module filesets.
if (!this->SourceEntries.empty() ||
!this->Target->GetHeaderSetsEntries().empty() ||
!this->Target->GetCxxModuleSetsEntries().empty()) {
!this->Target->GetFileSetsEntries(cmFileSet::HEADERS).empty() ||
!this->Target->GetFileSetsEntries(cmFileSet::CXX_MODULES).empty()) {
return true;
}
break;
@@ -2342,7 +2342,7 @@ cmGeneratorTarget::GetClassifiedFlagsForSource(cmSourceFile const* sf,
std::string bmiFlags;
auto const* fs = this->GetFileSetForSource(config, sf);
if (fs && fs->GetType() == "CXX_MODULES"_s) {
if (fs && fs->GetType() == cmFileSet::CXX_MODULES) {
if (lang != "CXX"_s) {
mf->IssueMessage(
MessageType::FATAL_ERROR,
@@ -5782,8 +5782,8 @@ bool cmGeneratorTarget::AddHeaderSetVerification()
allVerifyTargetName, { cmStateEnums::TargetDomain::NATIVE });
auto fileSetEntries = isInterface
? this->Target->GetInterfaceHeaderSetsEntries()
: this->Target->GetHeaderSetsEntries();
? this->Target->GetInterfaceFileSetsEntries(cmFileSet::HEADERS)
: this->Target->GetFileSetsEntries(cmFileSet::HEADERS);
std::set<cmFileSet*> fileSets;
for (auto const& entry : fileSetEntries) {
@@ -6163,7 +6163,7 @@ bool cmGeneratorTarget::HaveCxx20ModuleSources(std::string* errorMessage) const
}
auto const& fs_type = file_set->GetType();
return fs_type == "CXX_MODULES"_s;
return fs_type == cmFileSet::CXX_MODULES;
});
}
@@ -6337,7 +6337,7 @@ bool cmGeneratorTarget::NeedDyndepForSource(std::string const& lang,
// Any file in `CXX_MODULES` file sets need scanned (it being `CXX` is
// enforced elsewhere).
auto const* fs = this->GetFileSetForSource(config, sf);
if (fs && fs->GetType() == "CXX_MODULES"_s) {
if (fs && fs->GetType() == cmFileSet::CXX_MODULES) {
return true;
}
+7 -5
View File
@@ -106,7 +106,7 @@ void addFileSetEntry(cmGeneratorTarget const* headTarget,
EvaluatedTargetPropertyEntry const& entry = entries.Entries.back();
for (auto const& file : entry.Values) {
auto* sf = headTarget->Makefile->GetOrCreateSource(file);
if (fileSet->GetType() == "HEADERS"_s) {
if (fileSet->GetType() == cmFileSet::HEADERS) {
sf->SetProperty("HEADER_FILE_ONLY", "TRUE");
}
@@ -131,7 +131,7 @@ void addFileSetEntry(cmGeneratorTarget const* headTarget,
}
}
if (!found) {
if (fileSet->GetType() == "HEADERS"_s) {
if (fileSet->GetType() == cmFileSet::HEADERS) {
headTarget->Makefile->GetOrCreateSourceGroup("Header Files")
->AddGroupFile(path);
}
@@ -146,13 +146,15 @@ void AddFileSetEntries(cmGeneratorTarget const* headTarget,
cmGeneratorExpressionDAGChecker* dagChecker,
EvaluatedTargetPropertyEntries& entries)
{
for (auto const& entry : headTarget->Target->GetHeaderSetsEntries()) {
for (auto const& entry :
headTarget->Target->GetFileSetsEntries(cmFileSet::HEADERS)) {
for (auto const& name : cmList{ entry.Value }) {
auto const* headerSet = headTarget->Target->GetFileSet(name);
addFileSetEntry(headTarget, context, dagChecker, headerSet, entries);
}
}
for (auto const& entry : headTarget->Target->GetCxxModuleSetsEntries()) {
for (auto const& entry :
headTarget->Target->GetFileSetsEntries(cmFileSet::CXX_MODULES)) {
for (auto const& name : cmList{ entry.Value }) {
auto const* cxxModuleSet = headTarget->Target->GetFileSet(name);
addFileSetEntry(headTarget, context, dagChecker, cxxModuleSet, entries);
@@ -400,7 +402,7 @@ void cmGeneratorTarget::ComputeKindedSources(KindedSources& files,
if (sf->GetCustomCommand()) {
kind = SourceKindCustomCommand;
} else if (!this->Target->IsNormal() && !this->Target->IsImported() &&
fs && (fs->GetType() == "CXX_MODULES"_s)) {
fs && (fs->GetType() == cmFileSet::CXX_MODULES)) {
kind = SourceKindCxxModuleSource;
} else if (this->Target->GetType() == cmStateEnums::UTILITY ||
this->Target->GetType() == cmStateEnums::INTERFACE_LIBRARY
+2 -2
View File
@@ -64,11 +64,11 @@ bool cmInstallFileSetGenerator::Compute(cmLocalGenerator* lg)
}
cmList interfaceFileSetEntries{ target.GetSafeProperty(
cmTarget::GetInterfaceFileSetsPropertyName(this->FileSet->GetType())) };
target.GetInterfaceFileSetsPropertyName(this->FileSet->GetType())) };
if (std::find(interfaceFileSetEntries.begin(), interfaceFileSetEntries.end(),
this->FileSetName) != interfaceFileSetEntries.end()) {
if (this->FileSet->GetType() == "HEADERS"_s) {
if (this->FileSet->GetType() == cmFileSet::HEADERS) {
this->Destination = this->FileSetDestinations.Headers;
} else {
this->Destination = this->FileSetDestinations.CXXModules;
+1 -1
View File
@@ -394,7 +394,7 @@ void cmMakefileTargetGenerator::WriteTargetBuildRules()
auto const it = file_set_map.find(path);
if (it != file_set_map.end()) {
auto const& file_set_type = it->second;
if (file_set_type == "CXX_MODULES"_s) {
if (file_set_type == cmFileSet::CXX_MODULES) {
if (sf->GetLanguage() != "CXX"_s) {
this->Makefile->IssueMessage(
MessageType::FATAL_ERROR,
+6 -6
View File
@@ -254,7 +254,7 @@ std::string cmNinjaTargetGenerator::ComputeFlagsForObject(
}
auto const* fs = this->GeneratorTarget->GetFileSetForSource(config, source);
if (fs && fs->GetType() == "CXX_MODULES"_s) {
if (fs && fs->GetType() == cmFileSet::CXX_MODULES) {
if (source->GetLanguage() != "CXX"_s) {
this->GetMakefile()->IssueMessage(
MessageType::FATAL_ERROR,
@@ -1056,9 +1056,9 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatements(
this->GeneratorTarget->GetFileSetForSource(
config, this->Makefile->GetOrCreateGeneratedSource(*it));
bool isVisible = fileset &&
cmFileSetVisibilityIsForInterface(fileset->GetVisibility());
cmFileSet::VisibilityIsForInterface(fileset->GetVisibility());
bool isIncludeable =
!fileset || cmFileSetTypeCanBeIncluded(fileset->GetType());
!fileset || cmFileSet::TypeCanBeIncluded(fileset->GetType());
if (fileset && isVisible && isIncludeable) {
++it;
continue;
@@ -1169,7 +1169,7 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatements(
if (!fs) {
continue;
}
if (fs->GetType() != "CXX_MODULES"_s) {
if (fs->GetType() != cmFileSet::CXX_MODULES) {
continue;
}
if (sf->GetLanguage().empty()) {
@@ -1177,8 +1177,8 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatements(
MessageType::FATAL_ERROR,
cmStrCat("Target \"", this->GeneratorTarget->GetName(),
"\" has source file\n ", sf->GetFullPath(),
"\nin a \"FILE_SET TYPE CXX_MODULES\" but it is not "
"scheduled for compilation."));
"\nin a \"FILE_SET TYPE ", cmFileSet::CXX_MODULES,
"\" but it is not scheduled for compilation."));
}
}
}
+64 -75
View File
@@ -157,7 +157,7 @@ struct FileSetType
cmTargetInternals const* impl,
std::string const& prop) const;
void AddFileSet(std::string const& name, cmFileSetVisibility vis,
void AddFileSet(std::string const& name, cmFileSet::Visibility vis,
cmListFileBacktrace bt);
};
@@ -649,8 +649,7 @@ public:
UsageRequirementProperty ImportedCxxModulesCompileOptions;
UsageRequirementProperty ImportedCxxModulesLinkLibraries;
FileSetType HeadersFileSets;
FileSetType CxxModulesFileSets;
std::unordered_map<cm::string_view, FileSetType> FileSetTypes;
cmTargetInternals();
@@ -704,17 +703,19 @@ cmTargetInternals::cmTargetInternals()
"IMPORTED_CXX_MODULES_COMPILE_FEATURES"_s)
, ImportedCxxModulesCompileOptions("IMPORTED_CXX_MODULES_COMPILE_OPTIONS"_s)
, ImportedCxxModulesLinkLibraries("IMPORTED_CXX_MODULES_LINK_LIBRARIES"_s)
, HeadersFileSets("HEADERS"_s, "HEADER_DIRS"_s, "HEADER_SET"_s,
"HEADER_DIRS_"_s, "HEADER_SET_"_s, "Header"_s,
"The default header set"_s, "Header set"_s,
FileSetEntries("HEADER_SETS"_s),
FileSetEntries("INTERFACE_HEADER_SETS"_s))
, CxxModulesFileSets("CXX_MODULES"_s, "CXX_MODULE_DIRS"_s,
"CXX_MODULE_SET"_s, "CXX_MODULE_DIRS_"_s,
"CXX_MODULE_SET_"_s, "C++ module"_s,
"The default C++ module set"_s, "C++ module set"_s,
FileSetEntries("CXX_MODULE_SETS"_s),
FileSetEntries("INTERFACE_CXX_MODULE_SETS"_s))
, FileSetTypes{
{ cmFileSet::HEADERS,
{ cmFileSet::HEADERS, "HEADER_DIRS"_s, "HEADER_SET"_s, "HEADER_DIRS_"_s,
"HEADER_SET_"_s, "Header"_s, "The default header set"_s,
"Header set"_s, FileSetEntries{ "HEADER_SETS"_s },
FileSetEntries{ "INTERFACE_HEADER_SETS"_s } } },
{ cmFileSet::CXX_MODULES,
{ cmFileSet::CXX_MODULES, "CXX_MODULE_DIRS"_s, "CXX_MODULE_SET"_s,
"CXX_MODULE_DIRS_"_s, "CXX_MODULE_SET_"_s, "C++ module"_s,
"The default C++ module set"_s, "C++ module set"_s,
FileSetEntries{ "CXX_MODULE_SETS"_s },
FileSetEntries{ "INTERFACE_CXX_MODULE_SETS"_s } } }
}
{
}
@@ -803,13 +804,13 @@ std::pair<bool, cmValue> FileSetType::ReadProperties(
return { did_read, value };
}
void FileSetType::AddFileSet(std::string const& name, cmFileSetVisibility vis,
cmListFileBacktrace bt)
void FileSetType::AddFileSet(std::string const& name,
cmFileSet::Visibility vis, cmListFileBacktrace bt)
{
if (cmFileSetVisibilityIsForSelf(vis)) {
if (cmFileSet::VisibilityIsForSelf(vis)) {
this->SelfEntries.Entries.emplace_back(name, bt);
}
if (cmFileSetVisibilityIsForInterface(vis)) {
if (cmFileSet::VisibilityIsForInterface(vis)) {
this->InterfaceEntries.Entries.emplace_back(name, std::move(bt));
}
}
@@ -1770,9 +1771,11 @@ void cmTarget::CopyCxxModulesEntries(cmTarget const* tgt)
// Copy the C++ module fileset entries from `tgt`'s `INTERFACE` to this
// target's `PRIVATE`.
this->impl->CxxModulesFileSets.SelfEntries.Entries.clear();
this->impl->CxxModulesFileSets.SelfEntries.Entries =
tgt->impl->CxxModulesFileSets.InterfaceEntries.Entries;
auto& entries =
this->impl->FileSetTypes.at(cmFileSet::CXX_MODULES).SelfEntries.Entries;
entries.clear();
entries = tgt->impl->FileSetTypes.at(cmFileSet::CXX_MODULES)
.InterfaceEntries.Entries;
}
void cmTarget::CopyCxxModulesProperties(cmTarget const* tgt)
@@ -1920,24 +1923,26 @@ void cmTarget::CopyCxxModulesProperties(cmTarget const* tgt)
}
}
cmBTStringRange cmTarget::GetHeaderSetsEntries() const
{
return cmMakeRange(this->impl->HeadersFileSets.SelfEntries.Entries);
namespace {
std::vector<BT<std::string>> EmptyEntries;
}
cmBTStringRange cmTarget::GetCxxModuleSetsEntries() const
cmBTStringRange cmTarget::GetFileSetsEntries(cm::string_view type) const
{
return cmMakeRange(this->impl->CxxModulesFileSets.SelfEntries.Entries);
if (cm::contains(this->impl->FileSetTypes, type)) {
return cmMakeRange(this->impl->FileSetTypes.at(type).SelfEntries.Entries);
}
return cmMakeRange(EmptyEntries);
}
cmBTStringRange cmTarget::GetInterfaceHeaderSetsEntries() const
cmBTStringRange cmTarget::GetInterfaceFileSetsEntries(
cm::string_view type) const
{
return cmMakeRange(this->impl->HeadersFileSets.InterfaceEntries.Entries);
}
cmBTStringRange cmTarget::GetInterfaceCxxModuleSetsEntries() const
{
return cmMakeRange(this->impl->CxxModulesFileSets.InterfaceEntries.Entries);
if (cm::contains(this->impl->FileSetTypes, type)) {
return cmMakeRange(
this->impl->FileSetTypes.at(type).InterfaceEntries.Entries);
}
return cmMakeRange(EmptyEntries);
}
namespace {
@@ -2131,14 +2136,9 @@ void cmTarget::SetProperty(std::string const& prop, cmValue value)
}
}
FileSetType* fileSetTypes[] = {
&this->impl->HeadersFileSets,
&this->impl->CxxModulesFileSets,
};
for (auto* fileSetType : fileSetTypes) {
if (fileSetType->WriteProperties(this, this->impl.get(), prop, value,
FileSetType::Action::Set)) {
for (auto& fileSetType : this->impl->FileSetTypes) {
if (fileSetType.second.WriteProperties(this, this->impl.get(), prop, value,
FileSetType::Action::Set)) {
return;
}
}
@@ -2251,14 +2251,9 @@ void cmTarget::AppendProperty(std::string const& prop,
}
}
FileSetType* fileSetTypes[] = {
&this->impl->HeadersFileSets,
&this->impl->CxxModulesFileSets,
};
for (auto* fileSetType : fileSetTypes) {
if (fileSetType->WriteProperties(this, this->impl.get(), prop, value,
FileSetType::Action::Append)) {
for (auto& fileSetType : this->impl->FileSetTypes) {
if (fileSetType.second.WriteProperties(this, this->impl.get(), prop, value,
FileSetType::Action::Append)) {
return;
}
}
@@ -2734,13 +2729,9 @@ cmValue cmTarget::GetProperty(std::string const& prop) const
// Check fileset properties.
{
FileSetType* fileSetTypes[] = {
&this->impl->HeadersFileSets,
&this->impl->CxxModulesFileSets,
};
for (auto* fileSetType : fileSetTypes) {
auto value = fileSetType->ReadProperties(this, this->impl.get(), prop);
for (auto const& fileSetType : this->impl->FileSetTypes) {
auto value =
fileSetType.second.ReadProperties(this, this->impl.get(), prop);
if (value.first) {
return value.second;
}
@@ -3163,39 +3154,36 @@ cmFileSet* cmTarget::GetFileSet(std::string const& name)
}
std::pair<cmFileSet*, bool> cmTarget::GetOrCreateFileSet(
std::string const& name, std::string const& type, cmFileSetVisibility vis)
std::string const& name, std::string const& type, cmFileSet::Visibility vis)
{
auto result = this->impl->FileSets.emplace(
name, cmFileSet(this->GetMakefile(), name, type, vis));
if (result.second) {
auto bt = this->impl->Makefile->GetBacktrace();
if (type == this->impl->HeadersFileSets.TypeName) {
this->impl->HeadersFileSets.AddFileSet(name, vis, std::move(bt));
} else if (type == this->impl->CxxModulesFileSets.TypeName) {
this->impl->CxxModulesFileSets.AddFileSet(name, vis, std::move(bt));
if (cm::contains(this->impl->FileSetTypes, type)) {
this->impl->FileSetTypes.at(type).AddFileSet(name, vis, std::move(bt));
}
}
return std::make_pair(&result.first->second, result.second);
}
std::string cmTarget::GetFileSetsPropertyName(std::string const& type)
std::string cmTarget::GetFileSetsPropertyName(std::string const& type) const
{
if (type == "HEADERS") {
return "HEADER_SETS";
}
if (type == "CXX_MODULES") {
return "CXX_MODULE_SETS";
if (cm::contains(this->impl->FileSetTypes, type)) {
return std::string{
this->impl->FileSetTypes.at(type).SelfEntries.PropertyName
};
}
return "";
}
std::string cmTarget::GetInterfaceFileSetsPropertyName(std::string const& type)
std::string cmTarget::GetInterfaceFileSetsPropertyName(
std::string const& type) const
{
if (type == "HEADERS") {
return "INTERFACE_HEADER_SETS";
}
if (type == "CXX_MODULES") {
return "INTERFACE_CXX_MODULE_SETS";
if (cm::contains(this->impl->FileSetTypes, type)) {
return std::string{
this->impl->FileSetTypes.at(type).InterfaceEntries.PropertyName
};
}
return "";
}
@@ -3223,8 +3211,9 @@ std::vector<std::string> cmTarget::GetAllInterfaceFileSets() const
}
};
appendEntries(this->impl->HeadersFileSets.InterfaceEntries.Entries);
appendEntries(this->impl->CxxModulesFileSets.InterfaceEntries.Entries);
for (auto const& fileSetType : this->impl->FileSetTypes) {
appendEntries(fileSetType.second.InterfaceEntries.Entries);
}
return result;
}
+6 -9
View File
@@ -15,6 +15,7 @@
#include <cm/optional>
#include "cmAlgorithms.h"
#include "cmFileSet.h"
#include "cmListFileCache.h"
#include "cmPolicies.h"
#include "cmStateTypes.h"
@@ -33,8 +34,6 @@ class cmSourceFile;
class cmTargetExport;
class cmTargetInternals;
enum class cmFileSetVisibility;
/** \class cmTarget
* \brief Represent a library or executable target loaded from a makefile.
*
@@ -324,11 +323,9 @@ public:
void CopyCxxModulesEntries(cmTarget const* tgt);
void CopyCxxModulesProperties(cmTarget const* tgt);
cmBTStringRange GetHeaderSetsEntries() const;
cmBTStringRange GetCxxModuleSetsEntries() const;
cmBTStringRange GetFileSetsEntries(cm::string_view type) const;
cmBTStringRange GetInterfaceHeaderSetsEntries() const;
cmBTStringRange GetInterfaceCxxModuleSetsEntries() const;
cmBTStringRange GetInterfaceFileSetsEntries(cm::string_view type) const;
enum class ImportArtifactMissingOk
{
@@ -349,13 +346,13 @@ public:
cmFileSet* GetFileSet(std::string const& name);
std::pair<cmFileSet*, bool> GetOrCreateFileSet(std::string const& name,
std::string const& type,
cmFileSetVisibility vis);
cmFileSet::Visibility vis);
std::vector<std::string> GetAllFileSetNames() const;
std::vector<std::string> GetAllInterfaceFileSets() const;
static std::string GetFileSetsPropertyName(std::string const& type);
static std::string GetInterfaceFileSetsPropertyName(std::string const& type);
std::string GetFileSetsPropertyName(std::string const& type) const;
std::string GetInterfaceFileSetsPropertyName(std::string const& type) const;
bool HasFileSets() const;
+20 -18
View File
@@ -236,8 +236,8 @@ bool TargetSourcesImpl::HandleOneFileSet(
(args.Type.empty() && args.FileSet[0] >= 'A' && args.FileSet[0] <= 'Z');
std::string type = isDefault ? args.FileSet : args.Type;
cmFileSetVisibility visibility =
cmFileSetVisibilityFromName(scope, this->Makefile);
cmFileSet::Visibility visibility =
cmFileSet::VisibilityFromName(scope, this->Makefile);
auto fileSet =
this->Target->GetOrCreateFileSet(args.FileSet, type, visibility);
@@ -254,30 +254,32 @@ bool TargetSourcesImpl::HandleOneFileSet(
this->SetError("Must specify a TYPE when creating file set");
return false;
}
if (type != "HEADERS"_s && type != "CXX_MODULES"_s) {
this->SetError(
R"(File set TYPE may only be "HEADERS" or "CXX_MODULES")");
if (!cmFileSet::IsKnownType(type)) {
this->SetError(cmStrCat("File set TYPE may only be \"",
cmFileSet::GetKnownTypes().join("\", \""), '"'));
return false;
}
if (cmFileSetVisibilityIsForSelf(visibility) &&
if (cmFileSet::VisibilityIsForSelf(visibility) &&
this->Target->GetType() == cmStateEnums::INTERFACE_LIBRARY &&
!this->Target->IsImported()) {
if (type == "CXX_MODULES"_s) {
this->SetError(R"(File set TYPE "CXX_MODULES" may not have "PUBLIC" )"
R"(or "PRIVATE" visibility on INTERFACE libraries.)");
if (type == cmFileSet::CXX_MODULES) {
this->SetError(
cmStrCat(R"(File set TYPE ")", cmFileSet::CXX_MODULES,
R"(" may not have "PUBLIC" )"
R"(or "PRIVATE" visibility on INTERFACE libraries.)"));
return false;
}
}
// FIXME(https://wg21.link/P3470): This condition can go
// away when interface-only module units are a thing.
if (cmFileSetVisibilityIsForInterface(visibility) &&
!cmFileSetVisibilityIsForSelf(visibility) &&
if (cmFileSet::VisibilityIsForInterface(visibility) &&
!cmFileSet::VisibilityIsForSelf(visibility) &&
!this->Target->IsImported()) {
if (type == "CXX_MODULES"_s) {
this->SetError(
R"(File set TYPE "CXX_MODULES" may not have "INTERFACE" visibility)");
if (type == cmFileSet::CXX_MODULES) {
this->SetError(cmStrCat(R"(File set TYPE ")", cmFileSet::CXX_MODULES,
R"(" may not have "INTERFACE" visibility)"));
return false;
}
}
@@ -298,7 +300,7 @@ bool TargetSourcesImpl::HandleOneFileSet(
this->SetError(
cmStrCat("Scope ", scope, " for file set \"", args.FileSet,
"\" does not match original scope ",
cmFileSetVisibilityToName(fileSet.first->GetVisibility())));
cmFileSet::VisibilityToName(fileSet.first->GetVisibility())));
return false;
}
}
@@ -315,16 +317,16 @@ bool TargetSourcesImpl::HandleOneFileSet(
if (!baseDirectories.empty()) {
fileSet.first->AddDirectoryEntry(
BT<std::string>(baseDirectories, this->Makefile->GetBacktrace()));
if (type == "HEADERS"_s) {
if (type == cmFileSet::HEADERS) {
for (auto const& dir : cmList{ baseDirectories }) {
auto interfaceDirectoriesGenex =
cmStrCat("$<BUILD_INTERFACE:", dir, '>');
if (cmFileSetVisibilityIsForSelf(visibility)) {
if (cmFileSet::VisibilityIsForSelf(visibility)) {
this->Target->AppendProperty("INCLUDE_DIRECTORIES",
interfaceDirectoriesGenex,
this->Makefile->GetBacktrace());
}
if (cmFileSetVisibilityIsForInterface(visibility)) {
if (cmFileSet::VisibilityIsForInterface(visibility)) {
this->Target->AppendProperty("INTERFACE_INCLUDE_DIRECTORIES",
interfaceDirectoriesGenex,
this->Makefile->GetBacktrace());
+8 -8
View File
@@ -2711,13 +2711,13 @@ void cmVisualStudio10TargetGenerator::WriteAllSources(Elem& e0)
if (si.Kind == cmGeneratorTarget::SourceKindObjectSource ||
si.Kind == cmGeneratorTarget::SourceKindUnityBatched) {
this->OutputSourceSpecificFlags(e2, si.Source);
} else if (fs && fs->GetType() == "CXX_MODULES"_s) {
} else if (fs && fs->GetType() == cmFileSet::CXX_MODULES) {
this->GeneratorTarget->Makefile->IssueMessage(
MessageType::FATAL_ERROR,
cmStrCat("Target \"", this->GeneratorTarget->GetName(),
"\" has source file\n ", si.Source->GetFullPath(),
"\nin a \"FILE_SET TYPE CXX_MODULES\" but it is not "
"scheduled for compilation."));
"\nin a \"FILE_SET TYPE ", cmFileSet::CXX_MODULES,
"\" but it is not scheduled for compilation."));
}
if (si.Source->GetPropertyAsBool("SKIP_PRECOMPILE_HEADERS")) {
e2.Element("PrecompiledHeader", "NotUsing");
@@ -2753,13 +2753,13 @@ void cmVisualStudio10TargetGenerator::WriteAllSources(Elem& e0)
}
this->FinishWritingSource(e2, toolSettings);
} else if (fs && fs->GetType() == "CXX_MODULES"_s) {
} else if (fs && fs->GetType() == cmFileSet::CXX_MODULES) {
this->GeneratorTarget->Makefile->IssueMessage(
MessageType::FATAL_ERROR,
cmStrCat("Target \"", this->GeneratorTarget->GetName(),
"\" has source file\n ", si.Source->GetFullPath(),
"\nin a \"FILE_SET TYPE CXX_MODULES\" but it is not "
"scheduled for compilation."));
"\nin a \"FILE_SET TYPE ", cmFileSet::CXX_MODULES,
"\" but it is not scheduled for compilation."));
}
}
@@ -2884,9 +2884,9 @@ void cmVisualStudio10TargetGenerator::OutputSourceSpecificFlags(
auto const* fs =
this->GeneratorTarget->GetFileSetForSource(config, source);
char const* compileAsPerConfig = compileAs;
if (fs && fs->GetType() == "CXX_MODULES"_s) {
if (fs && fs->GetType() == cmFileSet::CXX_MODULES) {
if (lang == "CXX"_s) {
if (fs->GetType() == "CXX_MODULES"_s) {
if (fs->GetType() == cmFileSet::CXX_MODULES) {
isCppModule = true;
if (shouldScanForModules &&
this->GlobalGenerator->IsScanDependenciesSupported()) {
@@ -502,7 +502,7 @@ static bool testCreateFromFileSet()
auto dummies = CreateDummies("Foo");
cmFileSet fileSet(dummies.Makefile.get(), "Foo", "HEADERS",
cmFileSetVisibility::Public);
cmFileSet::Visibility::Public);
BT<std::string> directory;
directory.Value = "c:/";
fileSet.AddDirectoryEntry(directory);
@@ -547,7 +547,7 @@ static bool testCreateFromFileSets()
auto dummies = CreateDummies("Foo");
cmFileSet fileSet(dummies.Makefile.get(), "Foo", "HEADERS",
cmFileSetVisibility::Public);
cmFileSet::Visibility::Public);
BT<std::string> directory;
directory.Value = "c:/";
fileSet.AddDirectoryEntry(directory);
@@ -1,4 +1,4 @@
^CMake Error at FileSetDefaultWrongType\.cmake:[0-9]+ \(target_sources\):
target_sources File set TYPE may only be "HEADERS" or "CXX_MODULES"
target_sources File set TYPE may only be "HEADERS", "CXX_MODULES"
Call Stack \(most recent call first\):
CMakeLists\.txt:[0-9]+ \(include\)$
@@ -1,4 +1,4 @@
^CMake Error at FileSetWrongType\.cmake:[0-9]+ \(target_sources\):
target_sources File set TYPE may only be "HEADERS" or "CXX_MODULES"
target_sources File set TYPE may only be "HEADERS", "CXX_MODULES"
Call Stack \(most recent call first\):
CMakeLists\.txt:[0-9]+ \(include\)$