FileSet management: Introduce dedicated classes for generation

To manage the generation step, introduce cmGeneratorFileSet and
cmGeneratorFileSets classes.
These reorganizations of the code are done in preparation of the
implementation of SOURCES file set type as well as user's file set types.

Issues: #27550, #27383
This commit is contained in:
Marc Chevrier
2026-02-19 17:35:56 +01:00
parent b45dcfd306
commit dee8799d16
44 changed files with 1265 additions and 939 deletions
+6
View File
@@ -268,6 +268,8 @@ add_library(
cmFilePathChecksum.h
cmFileSet.cxx
cmFileSet.h
cmFileSetMetadata.cxx
cmFileSetMetadata.h
cmFileTime.cxx
cmFileTime.h
cmFileTimeCache.cxx
@@ -300,6 +302,10 @@ add_library(
cmGeneratorExpressionParser.h
cmGeneratorExpression.cxx
cmGeneratorExpression.h
cmGeneratorFileSet.cxx
cmGeneratorFileSet.h
cmGeneratorFileSets.cxx
cmGeneratorFileSets.h
cmGeneratorTarget.cxx
cmGeneratorTarget.h
cmGeneratorTarget_CompatibleInterface.cxx
+4 -3
View File
@@ -17,8 +17,9 @@
#include "cmsys/FStream.hxx"
#include "cmComputeLinkInformation.h"
#include "cmFileSet.h"
#include "cmFileSetMetadata.h"
#include "cmGeneratedFileStream.h"
#include "cmGeneratorFileSet.h"
#include "cmGeneratorTarget.h"
#include "cmGlobalGenerator.h"
#include "cmListFileCache.h"
@@ -449,9 +450,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() == cmFileSet::CXX_MODULES) {
if (fs && fs->GetType() == cm::FileSetMetadata::CXX_MODULES) {
isCXXModule = true;
isPrivate = !cmFileSet::VisibilityIsForInterface(fs->GetVisibility());
isPrivate = !fs->IsForInterface();
}
}
+5 -3
View File
@@ -16,6 +16,7 @@
#include "cmsys/FStream.hxx"
#include "cmFileSet.h"
#include "cmFileSetMetadata.h"
#include "cmGeneratedFileStream.h"
#include "cmJSONState.h"
#include "cmListFileCache.h"
@@ -448,9 +449,10 @@ void cmCxxModuleMetadata::PopulateTarget(
std::string metadataDir =
cmSystemTools::GetFilenamePath(meta.MetadataFilePath);
auto fileSet = target.GetOrCreateFileSet(
std::string{ cmFileSet::CXX_MODULES },
std::string{ cmFileSet::CXX_MODULES }, cmFileSet::Visibility::Interface);
auto fileSet =
target.GetOrCreateFileSet(std::string{ cm::FileSetMetadata::CXX_MODULES },
std::string{ cm::FileSetMetadata::CXX_MODULES },
cm::FileSetMetadata::Visibility::Interface);
for (auto const& module : meta.Modules) {
std::string sourcePath = module.SourcePath;
+19 -17
View File
@@ -16,6 +16,7 @@
#include "cmDebuggerStackFrame.h"
#include "cmDebuggerVariables.h"
#include "cmFileSet.h"
#include "cmFileSetMetadata.h"
#include "cmGlobalGenerator.h"
#include "cmList.h"
#include "cmListFileCache.h"
@@ -195,18 +196,19 @@ std::shared_ptr<cmDebuggerVariables> cmDebuggerVariablesHelper::CreateIfAny(
return {};
}
static auto visibilityString = [](cmFileSet::Visibility visibility) {
switch (visibility) {
case cmFileSet::Visibility::Private:
return "Private";
case cmFileSet::Visibility::Public:
return "Public";
case cmFileSet::Visibility::Interface:
return "Interface";
default:
return "Unknown";
}
};
static auto visibilityString =
[](cm::FileSetMetadata::Visibility visibility) {
switch (visibility) {
case cm::FileSetMetadata::Visibility::Private:
return "Private";
case cm::FileSetMetadata::Visibility::Public:
return "Public";
case cm::FileSetMetadata::Visibility::Interface:
return "Interface";
default:
return "Unknown";
}
};
auto variables = std::make_shared<cmDebuggerVariables>(
variablesManager, name, supportsVariableType, [=]() {
@@ -305,15 +307,15 @@ std::shared_ptr<cmDebuggerVariables> cmDebuggerVariablesHelper::CreateIfAny(
targetVariables->AddSubVariables(
CreateIfAny(variablesManager, "CompileOptions", supportsVariableType,
target->GetCompileOptionsEntries()));
targetVariables->AddSubVariables(
CreateIfAny(variablesManager, "CxxModuleSets", supportsVariableType,
target->GetFileSetsEntries(cmFileSet::CXX_MODULES)));
targetVariables->AddSubVariables(CreateIfAny(
variablesManager, "CxxModuleSets", supportsVariableType,
target->GetFileSetsEntries(cm::FileSetMetadata::CXX_MODULES)));
targetVariables->AddSubVariables(
CreateIfAny(variablesManager, "HeaderSets", supportsVariableType,
target->GetFileSetsEntries(cmFileSet::HEADERS)));
target->GetFileSetsEntries(cm::FileSetMetadata::HEADERS)));
targetVariables->AddSubVariables(CreateIfAny(
variablesManager, "InterfaceHeaderSets", supportsVariableType,
target->GetInterfaceFileSetsEntries(cmFileSet::HEADERS)));
target->GetInterfaceFileSetsEntries(cm::FileSetMetadata::HEADERS)));
targetVariables->AddSubVariables(
CreateIfAny(variablesManager, "LinkDirectories", supportsVariableType,
target->GetLinkDirectoriesEntries()));
+33 -45
View File
@@ -20,10 +20,11 @@
#include "cmCxxModuleMetadata.h"
#include "cmExportBuildFileGenerator.h"
#include "cmExportSet.h"
#include "cmFileSet.h"
#include "cmFileSetMetadata.h"
#include "cmGenExContext.h"
#include "cmGeneratedFileStream.h"
#include "cmGeneratorExpression.h" // IWYU pragma: keep
#include "cmGeneratorFileSet.h"
#include "cmGeneratorTarget.h"
#include "cmGlobalGenerator.h"
#include "cmInstallCxxModuleBmiGenerator.h"
@@ -56,7 +57,6 @@ TdiSourceInfo CollationInformationSources(cmGeneratorTarget const* gt,
cm::GenEx::Context const context(gt->LocalGenerator, config);
TdiSourceInfo info;
cmTarget const* tgt = gt->Target;
auto all_file_sets = tgt->GetAllFileSetNames();
Json::Value& tdi_sources = info.Sources = Json::objectValue;
Json::Value& tdi_cxx_module_info = info.CxxModules = Json::objectValue;
@@ -93,37 +93,20 @@ TdiSourceInfo CollationInformationSources(cmGeneratorTarget const* gt,
}
}
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;
}
for (auto const* file_set : gt->GetAllFileSets()) {
auto fs_type = file_set->GetType();
// We only care about C++ module sources here.
if (fs_type != cmFileSet::CXX_MODULES) {
if (fs_type != cm::FileSetMetadata::CXX_MODULES) {
continue;
}
// Synthetic (BMI-only) targets do not build private C++ modules.
if (tgt->IsSynthetic() &&
file_set->GetVisibility() == cmFileSet::Visibility::Private) {
file_set->GetVisibility() ==
cm::FileSetMetadata::Visibility::Private) {
continue;
}
auto fileEntries = file_set->CompileFileEntries();
auto directoryEntries = file_set->CompileDirectoryEntries();
auto directories =
file_set->EvaluateDirectoryEntries(directoryEntries, context, 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, context,
gt);
}
auto files_per_dirs = file_set->GetFiles(context, gt);
Json::Value fs_dest = Json::nullValue;
for (auto const& ig : gt->Makefile->GetInstallGenerators()) {
@@ -139,7 +122,7 @@ TdiSourceInfo CollationInformationSources(cmGeneratorTarget const* gt,
// Detect duplicate sources.
std::set<std::string> visited_sources;
for (auto const& files_per_dir : files_per_dirs) {
for (auto const& files_per_dir : files_per_dirs.first) {
for (auto const& file : files_per_dir.second) {
auto const full_file = cmSystemTools::CollapseFullPath(file);
auto lookup = sf_map.find(full_file);
@@ -149,16 +132,18 @@ TdiSourceInfo CollationInformationSources(cmGeneratorTarget const* gt,
gt->Makefile->IssueMessage(
MessageType::AUTHOR_WARNING,
cmStrCat("Target \"", tgt->GetName(), "\" has source file\n ",
file, "\nin a \"FILE_SET TYPE ", cmFileSet::CXX_MODULES,
file, "\nin a \"FILE_SET TYPE ",
cm::FileSetMetadata::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 ", cmFileSet::CXX_MODULES,
"\" but it is not "
"scheduled for compilation."));
gt->Makefile->IssueMessage(MessageType::FATAL_ERROR,
cmStrCat("Target \"", tgt->GetName(),
"\" has source file\n ", file,
"\nin a \"FILE_SET TYPE ",
cm::FileSetMetadata::CXX_MODULES,
"\" but it is not "
"scheduled for compilation."));
continue;
}
visited_sources.insert(full_file);
@@ -211,8 +196,8 @@ TdiSourceInfo CollationInformationSources(cmGeneratorTarget const* gt,
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(cmFileSet::VisibilityToName(file_set->GetVisibility()));
tdi_module_info["visibility"] = std::string(
cm::FileSetMetadata::VisibilityToName(file_set->GetVisibility()));
tdi_module_info["destination"] = fs_dest;
}
}
@@ -403,7 +388,8 @@ struct CxxModuleFileSet
std::string RelativeDirectory;
std::string SourcePath;
std::string Type;
cmFileSet::Visibility Visibility = cmFileSet::Visibility::Private;
cm::FileSetMetadata::Visibility Visibility =
cm::FileSetMetadata::Visibility::Private;
cm::optional<std::string> Destination;
std::vector<std::string> IncludeDirectories;
std::vector<std::string> Definitions;
@@ -526,7 +512,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 = cmFileSet::VisibilityFromName(
fsi.Visibility = cm::FileSetMetadata::VisibilityFromName(
tdi_cxx_module_info["visibility"].asString(), nullptr);
auto const& tdi_fs_dest = tdi_cxx_module_info["destination"];
if (tdi_fs_dest.isString()) {
@@ -677,7 +663,7 @@ bool cmDyndepCollation::WriteDyndepMetadata(
cmStrCat("Output ", object.PrimaryOutput, " provides the `",
provides.LogicalName,
"` module but it is not found in a `FILE_SET` of type `",
cmFileSet::CXX_MODULES, '`'));
cm::FileSetMetadata::CXX_MODULES, '`'));
result = false;
}
@@ -717,10 +703,11 @@ bool cmDyndepCollation::WriteDyndepMetadata(
}
// Verify the fileset type for the object.
if (file_set.Type == cmFileSet::CXX_MODULES) {
if (file_set.Type == cm::FileSetMetadata::CXX_MODULES) {
if (!has_provides) {
cmSystemTools::Error(cmStrCat("Output ", object.PrimaryOutput,
" is of type `", cmFileSet::CXX_MODULES,
" is of type `",
cm::FileSetMetadata::CXX_MODULES,
"` but does not provide a module "
"interface unit or partition"));
result = false;
@@ -731,10 +718,11 @@ bool cmDyndepCollation::WriteDyndepMetadata(
} 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 `", cmFileSet::CXX_MODULES, '`'));
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 `",
cm::FileSetMetadata::CXX_MODULES, '`'));
result = false;
}
@@ -742,7 +730,7 @@ bool cmDyndepCollation::WriteDyndepMetadata(
continue;
}
if (!cmFileSet::VisibilityIsForInterface(file_set.Visibility)) {
if (!cm::FileSetMetadata::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 +914,7 @@ bool cmDyndepCollation::IsObjectPrivate(
return false;
}
auto const& file_set = fileset_info_itr->second;
return !cmFileSet::VisibilityIsForInterface(file_set.Visibility);
return !cm::FileSetMetadata::VisibilityIsForInterface(file_set.Visibility);
}
bool cmDyndepCollation::IsBmiOnly(cmCxxModuleExportInfo const& exportInfo,
+4 -4
View File
@@ -10,6 +10,8 @@
#include "cmListFileCache.h"
namespace cm {
class TargetPropertyEntry;
namespace GenEx {
struct Context;
}
@@ -40,8 +42,7 @@ struct EvaluatedTargetPropertyEntry
EvaluatedTargetPropertyEntry EvaluateTargetPropertyEntry(
cmGeneratorTarget const* thisTarget, cm::GenEx::Context const& context,
cmGeneratorExpressionDAGChecker* dagChecker,
cmGeneratorTarget::TargetPropertyEntry& entry);
cmGeneratorExpressionDAGChecker* dagChecker, cm::TargetPropertyEntry& entry);
struct EvaluatedTargetPropertyEntries
{
@@ -52,8 +53,7 @@ struct EvaluatedTargetPropertyEntries
EvaluatedTargetPropertyEntries EvaluateTargetPropertyEntries(
cmGeneratorTarget const* thisTarget, cm::GenEx::Context const& context,
cmGeneratorExpressionDAGChecker* dagChecker,
std::vector<std::unique_ptr<cmGeneratorTarget::TargetPropertyEntry>> const&
in);
std::vector<std::unique_ptr<cm::TargetPropertyEntry>> const& in);
// IncludeRuntimeInterface is used to break the cycle in computing
// the necessary transitive dependencies of targets that can occur
+29 -56
View File
@@ -2,25 +2,23 @@
file LICENSE.rst or https://cmake.org/licensing for details. */
#include "cmExportBuildCMakeConfigGenerator.h"
#include <algorithm>
#include <cstddef>
#include <functional>
#include <map>
#include <memory>
#include <ostream>
#include <set>
#include <sstream>
#include <utility>
#include <vector>
#include <cm/string_view>
#include <cmext/string_view>
#include "cmCryptoHash.h"
#include "cmExportSet.h"
#include "cmFileSet.h"
#include "cmFileSetMetadata.h"
#include "cmGenExContext.h"
#include "cmGeneratedFileStream.h"
#include "cmGeneratorExpression.h"
#include "cmGeneratorFileSet.h"
#include "cmGeneratorTarget.h"
#include "cmLocalGenerator.h"
#include "cmMakefile.h"
@@ -160,47 +158,35 @@ void cmExportBuildCMakeConfigGenerator::GenerateImportTargetsConfig(
}
}
namespace {
bool EntryIsContextSensitive(
std::unique_ptr<cmCompiledGeneratorExpression> const& cge)
{
return cge->GetHadContextSensitiveCondition();
}
}
std::string cmExportBuildCMakeConfigGenerator::GetFileSetDirectories(
cmGeneratorTarget* gte, cmFileSet* fileSet, cmTargetExport const* /*te*/)
cmGeneratorTarget* gte, cmGeneratorFileSet const* fileSet,
cmTargetExport const* /*te*/)
{
std::vector<std::string> resultVector;
auto configs =
gte->Makefile->GetGeneratorConfigs(cmMakefile::IncludeEmptyConfig);
auto directoryEntries = fileSet->CompileDirectoryEntries();
for (auto const& config : configs) {
cm::GenEx::Context context(gte->LocalGenerator, config);
auto directories =
fileSet->EvaluateDirectoryEntries(directoryEntries, context, gte);
bool const contextSensitive =
std::any_of(directoryEntries.begin(), directoryEntries.end(),
EntryIsContextSensitive);
auto directories = fileSet->GetDirectories(context, gte);
bool const contextSensitive = directories.second;
auto const& type = fileSet->GetType();
// C++ modules do not support interface file sets which are dependent upon
// the configuration.
if (contextSensitive && type == cmFileSet::CXX_MODULES) {
if (contextSensitive && type == cm::FileSetMetadata::CXX_MODULES) {
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());
mf->IssueMessage(MessageType::FATAL_ERROR,
cmStrCat("The \"", gte->GetName(),
"\" target's interface file set \"",
fileSet->GetName(), "\" of type \"", type,
"\" contains context-sensitive base directory "
"entries which is not supported."));
return std::string{};
}
for (auto const& directory : directories) {
for (auto const& directory : directories.first) {
auto dest = cmOutputConverter::EscapeForCMake(
directory, cmOutputConverter::WrapQuotes::NoWrap);
@@ -217,47 +203,35 @@ std::string cmExportBuildCMakeConfigGenerator::GetFileSetDirectories(
}
std::string cmExportBuildCMakeConfigGenerator::GetFileSetFiles(
cmGeneratorTarget* gte, cmFileSet* fileSet, cmTargetExport const* /*te*/)
cmGeneratorTarget* gte, cmGeneratorFileSet const* fileSet,
cmTargetExport const* /*te*/)
{
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) {
cm::GenEx::Context context(gte->LocalGenerator, config);
auto directories =
fileSet->EvaluateDirectoryEntries(directoryEntries, context, gte);
std::map<std::string, std::vector<std::string>> files;
for (auto const& entry : fileEntries) {
fileSet->EvaluateFileEntry(directories, files, entry, context, gte);
}
bool const contextSensitive =
std::any_of(directoryEntries.begin(), directoryEntries.end(),
EntryIsContextSensitive) ||
std::any_of(fileEntries.begin(), fileEntries.end(),
EntryIsContextSensitive);
auto files = fileSet->GetFiles(context, gte);
bool const contextSensitive = files.second;
auto const& type = fileSet->GetType();
// C++ modules do not support interface file sets which are dependent upon
// the configuration.
if (contextSensitive && type == cmFileSet::CXX_MODULES) {
if (contextSensitive && type == cm::FileSetMetadata::CXX_MODULES) {
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());
mf->IssueMessage(MessageType::FATAL_ERROR,
cmStrCat("The \"", gte->GetName(),
"\" target's interface file set \"",
fileSet->GetName(), "\" of type \"", type,
"\" contains context-sensitive file entries "
"which is not supported."));
return std::string{};
}
for (auto const& it : files) {
for (auto const& it : files.first) {
for (auto const& filename : it.second) {
auto escapedFile = cmOutputConverter::EscapeForCMake(
filename, cmOutputConverter::WrapQuotes::NoWrap);
@@ -317,9 +291,8 @@ bool cmExportBuildCMakeConfigGenerator::
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());
cmSystemTools::Error(
cmStrCat("cannot write to file \"", fileName, "\": ", se));
return false;
}
os.SetCopyIfDifferent(true);
+4 -2
View File
@@ -36,9 +36,11 @@ protected:
void GenerateImportTargetsConfig(std::ostream& os, std::string const& config,
std::string const& suffix) override;
std::string GetFileSetDirectories(cmGeneratorTarget* gte, cmFileSet* fileSet,
std::string GetFileSetDirectories(cmGeneratorTarget* gte,
cmGeneratorFileSet const* fileSet,
cmTargetExport const* te) override;
std::string GetFileSetFiles(cmGeneratorTarget* gte, cmFileSet* fileSet,
std::string GetFileSetFiles(cmGeneratorTarget* gte,
cmGeneratorFileSet const* fileSet,
cmTargetExport const* te) override;
void GenerateCxxModuleConfigInformation(std::string const&,
+5 -4
View File
@@ -13,9 +13,10 @@
#include <cmext/string_view>
#include "cmExportSet.h"
#include "cmFileSet.h"
#include "cmFileSetMetadata.h"
#include "cmFindPackageStack.h"
#include "cmGeneratedFileStream.h"
#include "cmGeneratorFileSet.h"
#include "cmGeneratorTarget.h"
#include "cmLocalGenerator.h"
#include "cmMakefile.h"
@@ -607,7 +608,7 @@ void cmExportCMakeConfigGenerator::GenerateTargetFileSets(
<< targetName << '\n';
for (auto const& name : interfaceFileSets) {
auto* fileSet = gte->Target->GetFileSet(name);
auto const* fileSet = gte->GetFileSet(name);
if (!fileSet) {
gte->Makefile->IssueMessage(
MessageType::FATAL_ERROR,
@@ -629,7 +630,7 @@ void cmExportCMakeConfigGenerator::GenerateTargetFileSets(
os << " )\nelse()\n set_property(TARGET " << targetName
<< "\n APPEND PROPERTY INTERFACE_INCLUDE_DIRECTORIES";
for (auto const& name : interfaceFileSets) {
auto* fileSet = gte->Target->GetFileSet(name);
auto const* fileSet = gte->GetFileSet(name);
if (!fileSet) {
gte->Makefile->IssueMessage(
MessageType::FATAL_ERROR,
@@ -639,7 +640,7 @@ void cmExportCMakeConfigGenerator::GenerateTargetFileSets(
return;
}
if (fileSet->GetType() == cmFileSet::HEADERS) {
if (fileSet->GetType() == cm::FileSetMetadata::HEADERS) {
os << "\n " << this->GetFileSetDirectories(gte, fileSet, te);
}
}
+3 -3
View File
@@ -15,7 +15,7 @@
#include "cmGeneratorExpression.h"
#include "cmStateTypes.h"
class cmFileSet;
class cmGeneratorFileSet;
class cmGeneratorTarget;
class cmTargetExport;
@@ -91,10 +91,10 @@ protected:
void GenerateCxxModuleInformation(std::string const& name, std::ostream& os);
virtual std::string GetFileSetDirectories(cmGeneratorTarget* gte,
cmFileSet* fileSet,
cmGeneratorFileSet const* fileSet,
cmTargetExport const* te) = 0;
virtual std::string GetFileSetFiles(cmGeneratorTarget* gte,
cmFileSet* fileSet,
cmGeneratorFileSet const* fileSet,
cmTargetExport const* te) = 0;
void SetRequiredCMakeVersion(unsigned int major, unsigned int minor,
+2 -2
View File
@@ -674,9 +674,9 @@ bool PropertyTypeIsForPaths(PropertyType pt)
bool cmExportFileGenerator::PopulateCxxModuleExportProperties(
cmGeneratorTarget const* gte, ImportPropertyMap& properties,
cmGeneratorExpression::PreprocessContext ctx,
std::string const& includesDestinationDirs, std::string& errorMessage)
std::string const& includesDestinationDirs, std::string&)
{
if (!gte->HaveCxx20ModuleSources(&errorMessage)) {
if (!gte->HaveCxx20ModuleSources()) {
return true;
}
+18 -37
View File
@@ -2,7 +2,6 @@
file LICENSE.rst or https://cmake.org/licensing for details. */
#include "cmExportInstallCMakeConfigGenerator.h"
#include <algorithm>
#include <functional>
#include <map>
#include <memory>
@@ -12,14 +11,14 @@
#include <vector>
#include <cm/string_view>
#include <cmext/string_view>
#include "cmExportFileGenerator.h"
#include "cmExportSet.h"
#include "cmFileSet.h"
#include "cmFileSetMetadata.h"
#include "cmGenExContext.h"
#include "cmGeneratedFileStream.h"
#include "cmGeneratorExpression.h"
#include "cmGeneratorFileSet.h"
#include "cmGeneratorTarget.h"
#include "cmInstallExportGenerator.h"
#include "cmInstallFileSetGenerator.h"
@@ -271,16 +270,9 @@ void cmExportInstallCMakeConfigGenerator::GenerateImportTargetsConfig(
}
}
namespace {
bool EntryIsContextSensitive(
std::unique_ptr<cmCompiledGeneratorExpression> const& cge)
{
return cge->GetHadContextSensitiveCondition();
}
}
std::string cmExportInstallCMakeConfigGenerator::GetFileSetDirectories(
cmGeneratorTarget* gte, cmFileSet* fileSet, cmTargetExport const* te)
cmGeneratorTarget* gte, cmGeneratorFileSet const* fileSet,
cmTargetExport const* te)
{
std::vector<std::string> resultVector;
@@ -303,7 +295,7 @@ std::string cmExportInstallCMakeConfigGenerator::GetFileSetDirectories(
// C++ modules do not support interface file sets which are dependent upon
// the configuration.
if (cge->GetHadContextSensitiveCondition() &&
type == cmFileSet::CXX_MODULES) {
type == cm::FileSetMetadata::CXX_MODULES) {
auto* mf = this->IEGen->GetLocalGenerator()->GetMakefile();
std::ostringstream e;
e << "The \"" << gte->GetName() << "\" target's interface file set \""
@@ -327,29 +319,22 @@ std::string cmExportInstallCMakeConfigGenerator::GetFileSetDirectories(
}
std::string cmExportInstallCMakeConfigGenerator::GetFileSetFiles(
cmGeneratorTarget* gte, cmFileSet* fileSet, cmTargetExport const* te)
cmGeneratorTarget* gte, cmGeneratorFileSet const* fileSet,
cmTargetExport const* te)
{
std::vector<std::string> resultVector;
auto configs =
gte->Makefile->GetGeneratorConfigs(cmMakefile::IncludeEmptyConfig);
auto fileEntries = fileSet->CompileFileEntries();
auto directoryEntries = fileSet->CompileDirectoryEntries();
cmGeneratorExpression destGe(*gte->Makefile->GetCMakeInstance());
auto destCge = destGe.Parse(
te->FileSetGenerators.at(fileSet->GetName())->GetDestination());
for (auto const& config : configs) {
cm::GenEx::Context context(gte->LocalGenerator, config);
auto directories =
fileSet->EvaluateDirectoryEntries(directoryEntries, context, gte);
auto files = fileSet->GetFiles(context, gte);
std::map<std::string, std::vector<std::string>> files;
for (auto const& entry : fileEntries) {
fileSet->EvaluateFileEntry(directories, files, entry, context, gte);
}
auto unescapedDest = destCge->Evaluate(gte->LocalGenerator, config, gte);
auto dest =
cmStrCat(cmOutputConverter::EscapeForCMake(
@@ -359,27 +344,23 @@ std::string cmExportInstallCMakeConfigGenerator::GetFileSetFiles(
dest = cmStrCat("${_IMPORT_PREFIX}/", dest);
}
bool const contextSensitive = destCge->GetHadContextSensitiveCondition() ||
std::any_of(directoryEntries.begin(), directoryEntries.end(),
EntryIsContextSensitive) ||
std::any_of(fileEntries.begin(), fileEntries.end(),
EntryIsContextSensitive);
bool const contextSensitive =
destCge->GetHadContextSensitiveCondition() || files.second;
auto const& type = fileSet->GetType();
// C++ modules do not support interface file sets which are dependent upon
// the configuration.
if (contextSensitive && type == cmFileSet::CXX_MODULES) {
if (contextSensitive && type == cm::FileSetMetadata::CXX_MODULES) {
auto* mf = this->IEGen->GetLocalGenerator()->GetMakefile();
std::ostringstream e;
e << "The \"" << gte->GetName() << "\" target's interface file set \""
<< fileSet->GetName() << "\" of type \"" << type
<< "\" contains context-sensitive base file entries which is not "
"supported.";
mf->IssueMessage(MessageType::FATAL_ERROR, e.str());
mf->IssueMessage(MessageType::FATAL_ERROR,
cmStrCat("The \"", gte->GetName(),
"\" target's interface file set \"",
fileSet->GetName(), "\" of type \"", type,
"\" contains context-sensitive base file "
"entries which is not supported."));
return std::string{};
}
for (auto const& it : files) {
for (auto const& it : files.first) {
auto prefix = it.first.empty() ? "" : cmStrCat(it.first, '/');
for (auto const& filename : it.second) {
auto relFile =
+4 -2
View File
@@ -59,9 +59,11 @@ protected:
virtual void CleanupTemporaryVariables(std::ostream&);
std::string GetFileSetDirectories(cmGeneratorTarget* gte, cmFileSet* fileSet,
std::string GetFileSetDirectories(cmGeneratorTarget* gte,
cmGeneratorFileSet const* fileSet,
cmTargetExport const* te) override;
std::string GetFileSetFiles(cmGeneratorTarget* gte, cmFileSet* fileSet,
std::string GetFileSetFiles(cmGeneratorTarget* gte,
cmGeneratorFileSet const* fileSet,
cmTargetExport const* te) override;
std::string GetCxxModulesDirectory() const override;
@@ -19,8 +19,9 @@
#include "cmAlgorithms.h"
#include "cmExportSet.h"
#include "cmFileSet.h"
#include "cmFileSetMetadata.h"
#include "cmGeneratorExpression.h"
#include "cmGeneratorFileSet.h"
#include "cmGeneratorTarget.h"
#include "cmInstallExportGenerator.h"
#include "cmInstallFileSetGenerator.h"
@@ -220,8 +221,8 @@ std::string cmExportInstallPackageInfoGenerator::GetCxxModulesDirectory() const
cm::optional<std::string>
cmExportInstallPackageInfoGenerator::GetFileSetDirectory(
cmGeneratorTarget* gte, cmTargetExport const* te, cmFileSet* fileSet,
cm::optional<std::string> const& config)
cmGeneratorTarget* gte, cmTargetExport const* te,
cmGeneratorFileSet const* fileSet, cm::optional<std::string> const& config)
{
cmGeneratorExpression ge(*gte->Makefile->GetCMakeInstance());
auto cge =
@@ -240,7 +241,7 @@ cmExportInstallPackageInfoGenerator::GetFileSetDirectory(
}
std::string const& type = fileSet->GetType();
if (config && (type == cmFileSet::CXX_MODULES)) {
if (config && (type == cm::FileSetMetadata::CXX_MODULES)) {
// C++ modules do not support interface file sets which are dependent
// upon the configuration.
cmMakefile* mf = gte->LocalGenerator->GetMakefile();
@@ -270,7 +271,7 @@ bool cmExportInstallPackageInfoGenerator::GenerateFileSetProperties(
bool hasModules = false;
std::set<std::string> seenIncludeDirectories;
for (auto const& name : gte->Target->GetAllInterfaceFileSets()) {
cmFileSet* fileSet = gte->Target->GetFileSet(name);
cmGeneratorFileSet const* fileSet = gte->GetFileSet(name);
if (!fileSet) {
gte->Makefile->IssueMessage(
@@ -284,13 +285,13 @@ bool cmExportInstallPackageInfoGenerator::GenerateFileSetProperties(
cm::optional<std::string> const& fileSetDirectory =
this->GetFileSetDirectory(gte, te, fileSet, config);
if (fileSet->GetType() == cmFileSet::HEADERS) {
if (fileSet->GetType() == cm::FileSetMetadata::HEADERS) {
if (fileSetDirectory &&
!cm::contains(seenIncludeDirectories, *fileSetDirectory)) {
component["includes"].append(*fileSetDirectory);
seenIncludeDirectories.insert(*fileSetDirectory);
}
} else if (fileSet->GetType() == cmFileSet::CXX_MODULES) {
} else if (fileSet->GetType() == cm::FileSetMetadata::CXX_MODULES) {
hasModules = true;
this->RequiresConfigFiles = true;
}
+3 -2
View File
@@ -12,7 +12,7 @@
#include "cmExportInstallFileGenerator.h"
#include "cmExportPackageInfoGenerator.h"
class cmFileSet;
class cmGeneratorFileSet;
class cmGeneratorTarget;
class cmInstallExportGenerator;
class cmPackageInfoArguments;
@@ -71,7 +71,8 @@ protected:
std::string GetCxxModulesDirectory() const override;
cm::optional<std::string> GetFileSetDirectory(
cmGeneratorTarget* gte, cmTargetExport const* te, cmFileSet* fileSet,
cmGeneratorTarget* gte, cmTargetExport const* te,
cmGeneratorFileSet const* fileSet,
cm::optional<std::string> const& config = {});
bool GenerateFileSetProperties(Json::Value& component,
+5 -4
View File
@@ -13,8 +13,9 @@
#include <cmext/string_view>
#include "cmExportSet.h"
#include "cmFileSet.h"
#include "cmFileSetMetadata.h"
#include "cmGeneratorExpression.h"
#include "cmGeneratorFileSet.h"
#include "cmGeneratorTarget.h"
#include "cmInstallExportGenerator.h"
#include "cmInstallFileSetGenerator.h"
@@ -212,8 +213,8 @@ std::string cmExportInstallSbomGenerator::GetCxxModuleFile(
}
cm::optional<std::string> cmExportInstallSbomGenerator::GetFileSetDirectory(
cmGeneratorTarget* gte, cmTargetExport const* te, cmFileSet* fileSet,
cm::optional<std::string> const& config)
cmGeneratorTarget* gte, cmTargetExport const* te,
cmGeneratorFileSet const* fileSet, cm::optional<std::string> const& config)
{
cmGeneratorExpression ge(*gte->Makefile->GetCMakeInstance());
auto cge =
@@ -228,7 +229,7 @@ cm::optional<std::string> cmExportInstallSbomGenerator::GetFileSetDirectory(
}
std::string const& type = fileSet->GetType();
if (config && (type == cmFileSet::CXX_MODULES)) {
if (config && (type == cm::FileSetMetadata::CXX_MODULES)) {
cmMakefile* mf = gte->LocalGenerator->GetMakefile();
std::ostringstream e;
e << "The \"" << gte->GetName() << "\" target's interface file set \""
+3 -2
View File
@@ -13,7 +13,7 @@
#include "cmExportInstallFileGenerator.h"
#include "cmExportSbomGenerator.h"
class cmFileSet;
class cmGeneratorFileSet;
class cmGeneratorTarget;
class cmInstallExportGenerator;
class cmSbomArguments;
@@ -63,6 +63,7 @@ protected:
std::string GetCxxModulesDirectory() const override;
cm::optional<std::string> GetFileSetDirectory(
cmGeneratorTarget* gte, cmTargetExport const* te, cmFileSet* fileSet,
cmGeneratorTarget* gte, cmTargetExport const* te,
cmGeneratorFileSet const* fileSet,
cm::optional<std::string> const& config = {});
};
+5 -3
View File
@@ -8,10 +8,10 @@
#include <cm/memory>
#include <cmext/string_view>
#include "cmFileSet.h"
#include "cmGenExContext.h"
#include "cmGeneratorExpression.h"
#include "cmGeneratorExpressionDAGChecker.h"
#include "cmGeneratorFileSet.h"
#include "cmGeneratorTarget.h"
#include "cmGlobalGenerator.h"
#include "cmList.h"
@@ -176,14 +176,16 @@ std::string cmExportTryCompileFileGenerator::InstallNameDir(
}
std::string cmExportTryCompileFileGenerator::GetFileSetDirectories(
cmGeneratorTarget* /*gte*/, cmFileSet* fileSet, cmTargetExport const* /*te*/)
cmGeneratorTarget* /*gte*/, cmGeneratorFileSet const* fileSet,
cmTargetExport const* /*te*/)
{
return cmOutputConverter::EscapeForCMake(
cmList::to_string(fileSet->GetDirectoryEntries()));
}
std::string cmExportTryCompileFileGenerator::GetFileSetFiles(
cmGeneratorTarget* /*gte*/, cmFileSet* fileSet, cmTargetExport const* /*te*/)
cmGeneratorTarget* /*gte*/, cmGeneratorFileSet const* fileSet,
cmTargetExport const* /*te*/)
{
return cmOutputConverter::EscapeForCMake(
cmList::to_string(fileSet->GetFileEntries()));
+3 -2
View File
@@ -57,10 +57,11 @@ protected:
std::string const& config) override;
std::string GetFileSetDirectories(cmGeneratorTarget* target,
cmFileSet* fileSet,
cmGeneratorFileSet const* fileSet,
cmTargetExport const* te) override;
std::string GetFileSetFiles(cmGeneratorTarget* target, cmFileSet* fileSet,
std::string GetFileSetFiles(cmGeneratorTarget* target,
cmGeneratorFileSet const* fileSet,
cmTargetExport const* te) override;
std::string GetCxxModulesDirectory() const override { return {}; }
+19 -45
View File
@@ -17,16 +17,16 @@
#include <cm/string_view>
#include <cmext/algorithm>
#include <cmext/string_view>
#include <cm3p/json/value.h>
#include "cmCryptoHash.h"
#include "cmExportSet.h"
#include "cmFileAPI.h"
#include "cmFileSet.h"
#include "cmFileSetMetadata.h"
#include "cmGenExContext.h"
#include "cmGeneratorExpression.h"
#include "cmGeneratorFileSet.h"
#include "cmGeneratorTarget.h"
#include "cmGlobalGenerator.h"
#include "cmInstallCxxModuleBmiGenerator.h"
@@ -48,7 +48,6 @@
#include "cmListFileCache.h"
#include "cmLocalGenerator.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
#include "cmRange.h"
#include "cmSourceFile.h"
#include "cmSourceGroup.h"
@@ -465,7 +464,7 @@ class Target
using FileSetDatabase = std::map<std::string, Json::ArrayIndex>;
std::vector<cmFileSet::Visibility> FileSetVisibilities;
std::vector<cm::FileSetMetadata::Visibility> FileSetVisibilities;
template <typename T>
JBT<T> ToJBT(BT<T> const& bt)
@@ -502,7 +501,7 @@ class Target
Json::Value DumpLanguageStandard(JBTs<std::string> const& standard);
Json::Value DumpDefine(JBT<std::string> const& def);
std::pair<Json::Value, FileSetDatabase> DumpFileSets();
Json::Value DumpFileSet(cmFileSet const* fs,
Json::Value DumpFileSet(cmGeneratorFileSet const* fs,
std::vector<std::string> const& directories);
Json::Value DumpSources(FileSetDatabase const& fsdb);
Json::Value DumpSource(cmGeneratorTarget::SourceAndKind const& sk,
@@ -1148,18 +1147,11 @@ Json::Value DirectoryObject::DumpInstaller(cmInstallGenerator* gen)
auto* target = installFileSet->GetTarget();
cm::GenEx::Context context(target->LocalGenerator, this->Config);
auto dirCges = fileSet->CompileDirectoryEntries();
auto dirs = fileSet->EvaluateDirectoryEntries(dirCges, context, target);
auto entryCges = fileSet->CompileFileEntries();
std::map<std::string, std::vector<std::string>> entries;
for (auto const& entryCge : entryCges) {
fileSet->EvaluateFileEntry(dirs, entries, entryCge, context, target);
}
auto dirs = fileSet->GetDirectories(context, target);
auto entries = fileSet->GetFiles(context, target);
Json::Value files = Json::arrayValue;
for (auto const& it : entries) {
for (auto const& it : entries.first) {
auto dir = it.first;
if (!dir.empty()) {
dir += '/';
@@ -1174,7 +1166,7 @@ Json::Value DirectoryObject::DumpInstaller(cmInstallGenerator* gen)
installer["fileSetName"] = fileSet->GetName();
installer["fileSetType"] = fileSet->GetType();
installer["fileSetDirectories"] = Json::arrayValue;
for (auto const& dir : dirs) {
for (auto const& dir : dirs.first) {
installer["fileSetDirectories"].append(
RelativeIfUnder(this->TopSource, dir));
}
@@ -1726,41 +1718,22 @@ std::pair<Json::Value, Target::FileSetDatabase> Target::DumpFileSets()
this->FileSetVisibilities.clear();
// Build the fileset database.
auto const* tgt = this->GT->Target;
auto const& fs_names = tgt->GetAllFileSetNames();
auto const& fileSets = this->GT->GetAllFileSets();
if (!fs_names.empty()) {
if (!fileSets.empty()) {
fsJson = Json::arrayValue;
size_t fsIndex = 0;
for (auto const& fs_name : fs_names) {
auto const* fs = tgt->GetFileSet(fs_name);
if (!fs) {
this->GT->Makefile->IssueMessage(
MessageType::INTERNAL_ERROR,
cmStrCat("Target \"", tgt->GetName(),
"\" is tracked to have file set \"", fs_name,
"\", but it was not found."));
continue;
}
for (auto const* fs : fileSets) {
cm::GenEx::Context context(this->GT->LocalGenerator, this->Config);
auto fileEntries = fs->CompileFileEntries();
auto directoryEntries = fs->CompileDirectoryEntries();
auto directories = fs->GetDirectories(context, this->GT);
auto directories =
fs->EvaluateDirectoryEntries(directoryEntries, context, this->GT);
fsJson.append(this->DumpFileSet(fs, directories));
fsJson.append(this->DumpFileSet(fs, directories.first));
this->FileSetVisibilities.push_back(fs->GetVisibility());
std::map<std::string, std::vector<std::string>> files_per_dirs;
for (auto const& entry : fileEntries) {
fs->EvaluateFileEntry(directories, files_per_dirs, entry, context,
this->GT);
}
auto files_per_dirs = fs->GetFiles(context, this->GT);
for (auto const& files_per_dir : files_per_dirs) {
for (auto const& files_per_dir : files_per_dirs.first) {
auto const& dir = files_per_dir.first;
for (auto const& file : files_per_dir.second) {
std::string sf_path;
@@ -1780,7 +1753,7 @@ std::pair<Json::Value, Target::FileSetDatabase> Target::DumpFileSets()
return std::make_pair(fsJson, fsdb);
}
Json::Value Target::DumpFileSet(cmFileSet const* fs,
Json::Value Target::DumpFileSet(cmGeneratorFileSet const* fs,
std::vector<std::string> const& directories)
{
Json::Value fileSet = Json::objectValue;
@@ -1788,7 +1761,7 @@ Json::Value Target::DumpFileSet(cmFileSet const* fs,
fileSet["name"] = fs->GetName();
fileSet["type"] = fs->GetType();
fileSet["visibility"] =
std::string(cmFileSet::VisibilityToName(fs->GetVisibility()));
std::string(cm::FileSetMetadata::VisibilityToName(fs->GetVisibility()));
Json::Value baseDirs = Json::arrayValue;
for (auto const& directory : directories) {
@@ -1888,7 +1861,8 @@ 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] != cmFileSet::Visibility::Private) {
if (this->FileSetVisibilities[index] !=
cm::FileSetMetadata::Visibility::Private) {
dumpFile(fsIter.first);
}
}
+3 -233
View File
@@ -2,113 +2,24 @@
file LICENSE.rst or https://cmake.org/licensing for details. */
#include "cmFileSet.h"
#include <sstream>
#include <string>
#include <unordered_map>
#include <utility>
#include <vector>
#include <cm/optional>
#include <cmext/algorithm>
#include <cmext/string_view>
#include "cmsys/RegularExpression.hxx"
#include "cmGenExContext.h"
#include "cmGeneratorExpression.h"
#include "cmList.h"
#include "cmListFileCache.h"
#include "cmLocalGenerator.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmake.h"
cm::static_string_view cmFileSet::VisibilityToName(Visibility vis)
{
switch (vis) {
case Visibility::Interface:
return "INTERFACE"_s;
case Visibility::Public:
return "PUBLIC"_s;
case Visibility::Private:
return "PRIVATE"_s;
}
return ""_s;
}
cmFileSet::Visibility cmFileSet::VisibilityFromName(cm::string_view name,
cmMakefile* mf)
{
if (name == "INTERFACE"_s) {
return Visibility::Interface;
}
if (name == "PUBLIC"_s) {
return Visibility::Public;
}
if (name == "PRIVATE"_s) {
return Visibility::Private;
}
auto msg = cmStrCat("File set visibility \"", name, "\" is not valid.");
if (mf) {
mf->IssueMessage(MessageType::FATAL_ERROR, msg);
} else {
cmSystemTools::Error(msg);
}
return Visibility::Private;
}
bool cmFileSet::VisibilityIsForSelf(Visibility vis)
{
switch (vis) {
case Visibility::Interface:
return false;
case Visibility::Public:
case Visibility::Private:
return true;
}
return false;
}
bool cmFileSet::VisibilityIsForInterface(Visibility vis)
{
switch (vis) {
case Visibility::Interface:
case Visibility::Public:
return true;
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 cmFileSet::IsKnownType(std::string const& type)
{
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 } };
namespace Metadata = cm::FileSetMetadata;
cmFileSet::cmFileSet(cmMakefile* makefile, std::string name, std::string type,
Visibility visibility)
Metadata::Visibility visibility)
: Makefile(makefile)
, Name(std::move(name))
, Type(std::move(type))
, FSVisibility(visibility)
, Visibility(visibility)
{
}
@@ -138,147 +49,6 @@ void cmFileSet::AddFileEntry(BT<std::string> files)
this->FileEntries.push_back(std::move(files));
}
std::vector<std::unique_ptr<cmCompiledGeneratorExpression>>
cmFileSet::CompileFileEntries() const
{
std::vector<std::unique_ptr<cmCompiledGeneratorExpression>> result;
for (auto const& entry : this->FileEntries) {
for (auto const& ex : cmList{ entry.Value }) {
cmGeneratorExpression ge(*this->GetMakefile()->GetCMakeInstance(),
entry.Backtrace);
auto cge = ge.Parse(ex);
result.push_back(std::move(cge));
}
}
return result;
}
std::vector<std::unique_ptr<cmCompiledGeneratorExpression>>
cmFileSet::CompileDirectoryEntries() const
{
std::vector<std::unique_ptr<cmCompiledGeneratorExpression>> result;
for (auto const& entry : this->DirectoryEntries) {
for (auto const& ex : cmList{ entry.Value }) {
cmGeneratorExpression ge(*this->GetMakefile()->GetCMakeInstance(),
entry.Backtrace);
auto cge = ge.Parse(ex);
result.push_back(std::move(cge));
}
}
return result;
}
std::vector<std::string> cmFileSet::EvaluateDirectoryEntries(
std::vector<std::unique_ptr<cmCompiledGeneratorExpression>> const& cges,
cm::GenEx::Context const& context, cmGeneratorTarget const* target,
cmGeneratorExpressionDAGChecker* dagChecker) const
{
struct DirCacheEntry
{
std::string collapsedDir;
cm::optional<cmSystemTools::FileId> fileId;
};
std::unordered_map<std::string, DirCacheEntry> dirCache;
std::vector<std::string> result;
for (auto const& cge : cges) {
auto entry = cge->Evaluate(context, dagChecker, target);
cmList dirs{ entry };
for (std::string dir : dirs) {
if (!cmSystemTools::FileIsFullPath(dir)) {
dir = cmStrCat(context.LG->GetCurrentSourceDirectory(), '/', dir);
}
auto dirCacheResult = dirCache.emplace(dir, DirCacheEntry());
auto& dirCacheEntry = dirCacheResult.first->second;
auto const isNewCacheEntry = dirCacheResult.second;
if (isNewCacheEntry) {
cmSystemTools::FileId fileId;
auto isFileIdValid = cmSystemTools::GetFileId(dir, fileId);
dirCacheEntry.collapsedDir = cmSystemTools::CollapseFullPath(dir);
dirCacheEntry.fileId =
isFileIdValid ? cm::optional<decltype(fileId)>(fileId) : cm::nullopt;
}
for (auto const& priorDir : result) {
auto priorDirCacheEntry = dirCache.at(priorDir);
bool sameFile = dirCacheEntry.fileId.has_value() &&
priorDirCacheEntry.fileId.has_value() &&
(*dirCacheEntry.fileId == *priorDirCacheEntry.fileId);
if (!sameFile &&
(cmSystemTools::IsSubDirectory(dirCacheEntry.collapsedDir,
priorDirCacheEntry.collapsedDir) ||
cmSystemTools::IsSubDirectory(priorDirCacheEntry.collapsedDir,
dirCacheEntry.collapsedDir))) {
context.LG->GetCMakeInstance()->IssueMessage(
MessageType::FATAL_ERROR,
cmStrCat(
"Base directories in file set cannot be subdirectories of each "
"other:\n ",
priorDir, "\n ", dir),
cge->GetBacktrace());
return {};
}
}
result.push_back(dir);
}
}
return result;
}
void cmFileSet::EvaluateFileEntry(
std::vector<std::string> const& dirs,
std::map<std::string, std::vector<std::string>>& filesPerDir,
std::unique_ptr<cmCompiledGeneratorExpression> const& cge,
cm::GenEx::Context const& context, cmGeneratorTarget const* target,
cmGeneratorExpressionDAGChecker* dagChecker) const
{
auto files = cge->Evaluate(context, dagChecker, target);
for (std::string file : cmList{ files }) {
if (!cmSystemTools::FileIsFullPath(file)) {
file = cmStrCat(context.LG->GetCurrentSourceDirectory(), '/', file);
}
auto collapsedFile = cmSystemTools::CollapseFullPath(file);
bool found = false;
std::string relDir;
for (auto const& dir : dirs) {
auto collapsedDir = cmSystemTools::CollapseFullPath(dir);
if (cmSystemTools::IsSubDirectory(collapsedFile, collapsedDir)) {
found = true;
relDir = cmSystemTools::GetParentDirectory(
cmSystemTools::RelativePath(collapsedDir, collapsedFile));
break;
}
}
if (!found) {
std::ostringstream e;
e << "File:\n " << file
<< "\nmust be in one of the file set's base directories:";
for (auto const& dir : dirs) {
e << "\n " << dir;
}
context.LG->GetCMakeInstance()->IssueMessage(
MessageType::FATAL_ERROR, e.str(), cge->GetBacktrace());
return;
}
filesPerDir[relDir].push_back(file);
}
}
bool cmFileSet::IsValidName(std::string const& name)
{
static cmsys::RegularExpression const regex("^[a-z0-9][a-zA-Z0-9_]*$");
cmsys::RegularExpressionMatch match;
return regex.find(name.c_str(), match);
}
std::string const cmFileSet::propCOMPILE_DEFINITIONS = "COMPILE_DEFINITIONS";
std::string const cmFileSet::propCOMPILE_OPTIONS = "COMPILE_OPTIONS";
std::string const cmFileSet::propINCLUDE_DIRECTORIES = "INCLUDE_DIRECTORIES";
+21 -59
View File
@@ -3,63 +3,47 @@
#pragma once
#include <cstddef>
#include <map>
#include <memory>
#include <string>
#include <vector>
#include <cm/string_view>
#include <cmext/string_view>
#include "cmList.h"
#include "cmFileSetMetadata.h"
#include "cmListFileCache.h"
#include "cmPropertyMap.h"
#include "cmValue.h"
namespace cm {
namespace GenEx {
struct Context;
}
}
class cmCompiledGeneratorExpression;
struct cmGeneratorExpressionDAGChecker;
class cmGeneratorTarget;
class cmMakefile;
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,
Visibility visibility);
cm::FileSetMetadata::Visibility visibility);
std::string const& GetName() const { return this->Name; }
std::string const& GetType() const { return this->Type; }
Visibility GetVisibility() const { return this->FSVisibility; }
cm::FileSetMetadata::Visibility GetVisibility() const
{
return this->Visibility;
}
cmMakefile* GetMakefile() const { return this->Makefile; }
bool IsForSelf() const
{
return cm::FileSetMetadata::VisibilityIsForSelf(this->GetVisibility());
}
bool IsForInterface() const
{
return cm::FileSetMetadata::VisibilityIsForInterface(
this->GetVisibility());
}
bool CanBeIncluded() const
{
return this->Type == cm::FileSetMetadata::HEADERS;
}
void CopyEntries(cmFileSet const* fs);
void ClearDirectoryEntries();
@@ -76,26 +60,6 @@ public:
return this->FileEntries;
}
std::vector<std::unique_ptr<cmCompiledGeneratorExpression>>
CompileFileEntries() const;
std::vector<std::unique_ptr<cmCompiledGeneratorExpression>>
CompileDirectoryEntries() const;
std::vector<std::string> EvaluateDirectoryEntries(
std::vector<std::unique_ptr<cmCompiledGeneratorExpression>> const& cges,
cm::GenEx::Context const& context, cmGeneratorTarget const* target,
cmGeneratorExpressionDAGChecker* dagChecker = nullptr) const;
void EvaluateFileEntry(
std::vector<std::string> const& dirs,
std::map<std::string, std::vector<std::string>>& filesPerDir,
std::unique_ptr<cmCompiledGeneratorExpression> const& cge,
cm::GenEx::Context const& context, cmGeneratorTarget const* target,
cmGeneratorExpressionDAGChecker* dagChecker = nullptr) const;
static bool IsValidName(std::string const& name);
//! Set/Get a property of this file set
void SetProperty(std::string const& prop, cmValue value);
void SetProperty(std::string const& prop, std::nullptr_t)
@@ -115,12 +79,10 @@ public:
cmValue GetProperty(std::string const& prop) const;
private:
static cmList KnownTypes;
cmMakefile* Makefile;
std::string Name;
std::string Type;
Visibility FSVisibility;
cm::FileSetMetadata::Visibility Visibility;
std::vector<BT<std::string>> DirectoryEntries;
std::vector<BT<std::string>> FileEntries;
cmPropertyMap Properties;
+102
View File
@@ -0,0 +1,102 @@
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
file LICENSE.rst or https://cmake.org/licensing for details. */
#include "cmFileSetMetadata.h"
#include <string>
#include <cmext/algorithm>
#include <cmext/string_view>
#include "cmsys/RegularExpression.hxx"
#include "cmMakefile.h"
#include "cmMessageType.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
namespace cm {
namespace FileSetMetadata {
cm::string_view VisibilityToName(Visibility vis)
{
switch (vis) {
case Visibility::Interface:
return "INTERFACE"_s;
case Visibility::Public:
return "PUBLIC"_s;
case Visibility::Private:
return "PRIVATE"_s;
}
return ""_s;
}
Visibility VisibilityFromName(cm::string_view name, cmMakefile* mf)
{
if (name == "INTERFACE"_s) {
return Visibility::Interface;
}
if (name == "PUBLIC"_s) {
return Visibility::Public;
}
if (name == "PRIVATE"_s) {
return Visibility::Private;
}
auto msg = cmStrCat("File set visibility \"", name, "\" is not valid.");
if (mf) {
mf->IssueMessage(MessageType::FATAL_ERROR, msg);
} else {
cmSystemTools::Error(msg);
}
return Visibility::Private;
}
bool VisibilityIsForSelf(Visibility vis)
{
switch (vis) {
case Visibility::Interface:
return false;
case Visibility::Public:
case Visibility::Private:
return true;
}
return false;
}
bool VisibilityIsForInterface(Visibility vis)
{
switch (vis) {
case Visibility::Interface:
case Visibility::Public:
return true;
case Visibility::Private:
return false;
}
return false;
}
cm::string_view const HEADERS = "HEADERS"_s;
cm::string_view const CXX_MODULES = "CXX_MODULES"_s;
namespace {
std::vector<cm::string_view> KnownTypes{ HEADERS, CXX_MODULES };
cmsys::RegularExpression const ValidNameRegex("^[a-z0-9][a-zA-Z0-9_]*$");
}
std::vector<cm::string_view> const& GetKnownTypes()
{
return KnownTypes;
}
bool IsKnownType(cm::string_view type)
{
return cm::contains(GetKnownTypes(), type);
}
bool IsValidName(cm::string_view name)
{
cmsys::RegularExpressionMatch match;
return ValidNameRegex.find(name.data(), match);
}
}
}
+36
View File
@@ -0,0 +1,36 @@
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
file LICENSE.rst or https://cmake.org/licensing for details. */
#pragma once
#include <vector>
#include <cm/string_view>
class cmMakefile;
namespace cm {
namespace FileSetMetadata {
enum class Visibility
{
Private,
Public,
Interface
};
cm::string_view VisibilityToName(Visibility vis);
Visibility VisibilityFromName(cm::string_view name, cmMakefile* mf);
bool VisibilityIsForSelf(Visibility vis);
bool VisibilityIsForInterface(Visibility vis);
// Pre-defined FileSet types
extern cm::string_view const HEADERS;
extern cm::string_view const CXX_MODULES;
std::vector<cm::string_view> const& GetKnownTypes();
bool IsKnownType(cm::string_view type);
// check validity of a user's file set name
bool IsValidName(cm::string_view type);
}
}
+10 -6
View File
@@ -29,12 +29,12 @@
#include "cmCMakePath.h"
#include "cmCMakeString.hxx"
#include "cmComputeLinkInformation.h"
#include "cmFileSet.h"
#include "cmGenExContext.h"
#include "cmGenExEvaluation.h"
#include "cmGeneratorExpression.h"
#include "cmGeneratorExpressionDAGChecker.h"
#include "cmGeneratorExpressionEvaluator.h"
#include "cmGeneratorFileSet.h"
#include "cmGeneratorTarget.h"
#include "cmGlobalGenerator.h"
#include "cmLinkItem.h"
@@ -3582,11 +3582,11 @@ static const struct DeviceLinkNode : public cmGeneratorExpressionNode
namespace {
bool GetFileSet(std::vector<std::string> const& parameters,
cm::GenEx::Evaluation* eval,
GeneratorExpressionContent const* content, cmFileSet*& fileSet)
GeneratorExpressionContent const* content,
cmGeneratorFileSet const*& fileSet)
{
auto const& fileSetName = parameters[0];
auto targetName = parameters[1];
auto* makefile = eval->Context.LG->GetMakefile();
fileSet = nullptr;
auto const TARGET = "TARGET:"_s;
@@ -3598,7 +3598,11 @@ bool GetFileSet(std::vector<std::string> const& parameters,
cmStrCat("No value provided for the ", TARGET, " option."));
return false;
}
auto* target = makefile->FindTargetToUse(targetName);
cmLocalGenerator const* lg = eval->CurrentTarget
? eval->CurrentTarget->GetLocalGenerator()
: eval->Context.LG;
auto const* target = lg->FindGeneratorTargetToUse(targetName);
if (!target) {
reportError(eval, content->GetOriginalExpression(),
cmStrCat("Non-existent target: ", targetName));
@@ -3634,7 +3638,7 @@ static const struct FileSetExistsNode : public cmGeneratorExpressionNode
return std::string{};
}
cmFileSet* fileSet = nullptr;
cmGeneratorFileSet const* fileSet = nullptr;
if (!GetFileSet(parameters, eval, content, fileSet)) {
return std::string{};
}
@@ -3686,7 +3690,7 @@ static const struct FileSetPropertyNode : public cmGeneratorExpressionNode
return std::string{};
}
cmFileSet* fileSet = nullptr;
cmGeneratorFileSet const* fileSet = nullptr;
if (!GetFileSet(parameters, eval, content, fileSet)) {
return std::string{};
}
+337
View File
@@ -0,0 +1,337 @@
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
file LICENSE.rst or https://cmake.org/licensing for details. */
#include "cmGeneratorFileSet.h"
#include <algorithm>
#include <map>
#include <sstream>
#include <unordered_map>
#include <utility>
#include <vector>
#include <cm/memory>
#include <cm/optional>
#include "cmFileSet.h"
#include "cmGenExContext.h"
#include "cmGeneratorExpression.h"
#include "cmList.h"
#include "cmListFileCache.h"
#include "cmLocalGenerator.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmake.h"
class cmLinkItem;
class FileSetPropertyEntry : public cm::TargetPropertyEntry
{
public:
FileSetPropertyEntry(
std::vector<std::string> dirs, bool contextSensitiveDirs,
std::unique_ptr<cmCompiledGeneratorExpression> const& cge,
cmGeneratorFileSet const* fileSet, cmLinkItem const& item = NoLinkItem)
: cm::TargetPropertyEntry(item)
, BaseDirs(std::move(dirs))
, ContextSensitiveDirs(contextSensitiveDirs)
, Cge(cge)
, FileSet(fileSet)
{
}
static std::unique_ptr<cm::TargetPropertyEntry> CreateFileSetEntry(
std::vector<std::string> dirs, bool contextSensitiveDirs,
std::unique_ptr<cmCompiledGeneratorExpression> const& cge,
cmGeneratorFileSet const* fileSet, cmLinkItem const& item = NoLinkItem)
{
return cm::make_unique<FileSetPropertyEntry>(
std::move(dirs), contextSensitiveDirs, cge, fileSet, item);
}
std::string const& Evaluate(
cm::GenEx::Context const& context, cmGeneratorTarget const* headTarget,
cmGeneratorExpressionDAGChecker* dagChecker) const override
{
std::map<std::string, std::vector<std::string>> filesPerDir;
this->FileSet->EvaluateFileEntry(this->BaseDirs, filesPerDir, this->Cge,
context, headTarget, dagChecker);
std::vector<std::string> files;
for (auto const& it : filesPerDir) {
files.insert(files.end(), it.second.begin(), it.second.end());
}
this->Value = cmList::to_string(files);
return Value;
}
cmListFileBacktrace GetBacktrace() const override
{
return this->Cge->GetBacktrace();
}
std::string const& GetInput() const override
{
return this->Cge->GetInput();
}
bool GetHadContextSensitiveCondition() const override
{
return this->ContextSensitiveDirs ||
this->Cge->GetHadContextSensitiveCondition();
}
private:
std::vector<std::string> const BaseDirs;
bool const ContextSensitiveDirs;
std::unique_ptr<cmCompiledGeneratorExpression> const& Cge;
cmGeneratorFileSet const* FileSet;
mutable std::string Value;
};
//
// Class cmGeneratorFileSet
//
cmGeneratorFileSet::cmGeneratorFileSet(cmFileSet const* fileSet)
: FileSet(fileSet)
{
}
std::string const& cmGeneratorFileSet::GetName() const
{
return this->FileSet->GetName();
}
std::string const& cmGeneratorFileSet::GetType() const
{
return this->FileSet->GetType();
}
cm::FileSetMetadata::Visibility cmGeneratorFileSet::GetVisibility() const
{
return this->FileSet->GetVisibility();
}
bool cmGeneratorFileSet::IsForSelf() const
{
return this->FileSet->IsForSelf();
}
bool cmGeneratorFileSet::IsForInterface() const
{
return this->FileSet->IsForInterface();
}
bool cmGeneratorFileSet::CanBeIncluded() const
{
return this->FileSet->CanBeIncluded();
}
cmValue cmGeneratorFileSet::GetProperty(std::string const& prop) const
{
return this->FileSet->GetProperty(prop);
}
std::vector<BT<std::string>> const& cmGeneratorFileSet::GetDirectoryEntries()
const
{
return this->FileSet->GetDirectoryEntries();
}
std::vector<BT<std::string>> const& cmGeneratorFileSet::GetFileEntries() const
{
return this->FileSet->GetFileEntries();
}
std::vector<std::unique_ptr<cmCompiledGeneratorExpression>> const&
cmGeneratorFileSet::CompileFileEntries() const
{
if (this->CompiledFileEntries.empty() &&
!this->FileSet->GetFileEntries().empty()) {
for (auto const& entry : this->FileSet->GetFileEntries()) {
for (auto const& ex : cmList{ entry.Value }) {
cmGeneratorExpression ge(
*this->FileSet->GetMakefile()->GetCMakeInstance(), entry.Backtrace);
auto cge = ge.Parse(ex);
this->CompiledFileEntries.push_back(std::move(cge));
}
}
}
return this->CompiledFileEntries;
}
std::vector<std::unique_ptr<cmCompiledGeneratorExpression>> const&
cmGeneratorFileSet::CompileDirectoryEntries() const
{
if (this->CompiledDirectoryEntries.empty() &&
!this->FileSet->GetDirectoryEntries().empty()) {
for (auto const& entry : this->FileSet->GetDirectoryEntries()) {
for (auto const& ex : cmList{ entry.Value }) {
cmGeneratorExpression ge(
*this->FileSet->GetMakefile()->GetCMakeInstance(), entry.Backtrace);
auto cge = ge.Parse(ex);
this->CompiledDirectoryEntries.push_back(std::move(cge));
}
}
}
return this->CompiledDirectoryEntries;
}
std::vector<std::string> cmGeneratorFileSet::EvaluateDirectoryEntries(
std::vector<std::unique_ptr<cmCompiledGeneratorExpression>> const& cges,
cm::GenEx::Context const& context, cmGeneratorTarget const* target,
cmGeneratorExpressionDAGChecker* dagChecker) const
{
struct DirCacheEntry
{
std::string collapsedDir;
cm::optional<cmSystemTools::FileId> fileId;
};
std::unordered_map<std::string, DirCacheEntry> dirCache;
std::vector<std::string> result;
for (auto const& cge : cges) {
auto entry = cge->Evaluate(context, dagChecker, target);
cmList dirs{ entry };
for (std::string dir : dirs) {
if (!cmSystemTools::FileIsFullPath(dir)) {
dir = cmStrCat(context.LG->GetCurrentSourceDirectory(), '/', dir);
}
auto dirCacheResult = dirCache.emplace(dir, DirCacheEntry());
auto& dirCacheEntry = dirCacheResult.first->second;
auto const isNewCacheEntry = dirCacheResult.second;
if (isNewCacheEntry) {
cmSystemTools::FileId fileId;
auto isFileIdValid = cmSystemTools::GetFileId(dir, fileId);
dirCacheEntry.collapsedDir = cmSystemTools::CollapseFullPath(dir);
dirCacheEntry.fileId =
isFileIdValid ? cm::optional<decltype(fileId)>(fileId) : cm::nullopt;
}
for (auto const& priorDir : result) {
auto priorDirCacheEntry = dirCache.at(priorDir);
bool sameFile = dirCacheEntry.fileId.has_value() &&
priorDirCacheEntry.fileId.has_value() &&
(*dirCacheEntry.fileId == *priorDirCacheEntry.fileId);
if (!sameFile &&
(cmSystemTools::IsSubDirectory(dirCacheEntry.collapsedDir,
priorDirCacheEntry.collapsedDir) ||
cmSystemTools::IsSubDirectory(priorDirCacheEntry.collapsedDir,
dirCacheEntry.collapsedDir))) {
context.LG->GetCMakeInstance()->IssueMessage(
MessageType::FATAL_ERROR,
cmStrCat(
"Base directories in file set cannot be subdirectories of each "
"other:\n ",
priorDir, "\n ", dir),
cge->GetBacktrace());
return {};
}
}
result.push_back(dir);
}
}
return result;
}
void cmGeneratorFileSet::EvaluateFileEntry(
std::vector<std::string> const& dirs,
std::map<std::string, std::vector<std::string>>& filesPerDir,
std::unique_ptr<cmCompiledGeneratorExpression> const& cge,
cm::GenEx::Context const& context, cmGeneratorTarget const* target,
cmGeneratorExpressionDAGChecker* dagChecker) const
{
auto files = cge->Evaluate(context, dagChecker, target);
for (std::string file : cmList{ files }) {
if (!cmSystemTools::FileIsFullPath(file)) {
file = cmStrCat(context.LG->GetCurrentSourceDirectory(), '/', file);
}
auto collapsedFile = cmSystemTools::CollapseFullPath(file);
bool found = false;
std::string relDir;
for (auto const& dir : dirs) {
auto collapsedDir = cmSystemTools::CollapseFullPath(dir);
if (cmSystemTools::IsSubDirectory(collapsedFile, collapsedDir)) {
found = true;
relDir = cmSystemTools::GetParentDirectory(
cmSystemTools::RelativePath(collapsedDir, collapsedFile));
break;
}
}
if (!found) {
std::ostringstream e;
e << "File:\n " << file
<< "\nmust be in one of the file set's base directories:";
for (auto const& dir : dirs) {
e << "\n " << dir;
}
context.LG->GetCMakeInstance()->IssueMessage(
MessageType::FATAL_ERROR, e.str(), cge->GetBacktrace());
return;
}
filesPerDir[relDir].push_back(file);
}
}
namespace {
bool EntryIsContextSensitive(
std::unique_ptr<cmCompiledGeneratorExpression> const& cge)
{
return cge->GetHadContextSensitiveCondition();
}
}
std::vector<std::unique_ptr<cm::TargetPropertyEntry>>
cmGeneratorFileSet::GetSources(
cm::GenEx::Context const& context, cmGeneratorTarget const* target,
cmGeneratorExpressionDAGChecker* dagChecker) const
{
std::vector<std::unique_ptr<TargetPropertyEntry>> entries;
auto directories = this->GetDirectories(context, target, dagChecker);
bool contextSensitive = directories.second;
for (auto const& entry : this->CompileFileEntries()) {
auto propEntry = FileSetPropertyEntry::CreateFileSetEntry(
directories.first, contextSensitive, entry, this);
entries.push_back(std::move(propEntry));
}
return entries;
}
std::pair<std::vector<std::string>, bool> cmGeneratorFileSet::GetDirectories(
cm::GenEx::Context const& context, cmGeneratorTarget const* target,
cmGeneratorExpressionDAGChecker* dagChecker) const
{
auto const& directoryEntries = this->CompileDirectoryEntries();
auto directories = this->EvaluateDirectoryEntries(directoryEntries, context,
target, dagChecker);
bool contextSensitive = std::any_of(
directoryEntries.begin(), directoryEntries.end(), EntryIsContextSensitive);
return std::make_pair(std::move(directories), contextSensitive);
}
std::pair<std::map<std::string, std::vector<std::string>>, bool>
cmGeneratorFileSet::GetFiles(cm::GenEx::Context const& context,
cmGeneratorTarget const* target,
cmGeneratorExpressionDAGChecker* dagChecker) const
{
auto directories = this->GetDirectories(context, target, dagChecker);
auto const& fileEntries = this->CompileFileEntries();
std::map<std::string, std::vector<std::string>> files;
for (auto const& entry : fileEntries) {
this->EvaluateFileEntry(directories.first, files, entry, context, target,
dagChecker);
}
bool contextSensitive = directories.second ||
std::any_of(fileEntries.begin(), fileEntries.end(),
EntryIsContextSensitive);
return std::make_pair(std::move(files), contextSensitive);
}
+100
View File
@@ -0,0 +1,100 @@
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
file LICENSE.rst or https://cmake.org/licensing for details. */
#pragma once
#include "cmConfigure.h" // IWYU pragma: keep
#include <map>
#include <memory>
#include <string>
#include <utility>
#include <vector>
#include "cmFileSetMetadata.h"
#include "cmGeneratorExpression.h"
#include "cmTargetPropertyEntry.h"
#include "cmValue.h"
namespace cm {
namespace GenEx {
struct Context;
}
}
template <typename T>
class BT;
struct cmGeneratorExpressionDAGChecker;
class cmFileSet;
class cmGeneratorTarget;
class cmGeneratorFileSet
{
public:
using TargetPropertyEntry = cm::TargetPropertyEntry;
cmGeneratorFileSet(cmFileSet const*);
~cmGeneratorFileSet() = default;
cmGeneratorFileSet(cmGeneratorFileSet&&) = default;
cmGeneratorFileSet(cmGeneratorFileSet const&) = delete;
cmGeneratorFileSet& operator=(cmGeneratorFileSet const&) = delete;
std::string const& GetName() const;
std::string const& GetType() const;
cm::FileSetMetadata::Visibility GetVisibility() const;
bool IsForSelf() const;
bool IsForInterface() const;
bool CanBeIncluded() const;
cmFileSet const* GetFileSet() const { return this->FileSet; }
cmValue GetProperty(std::string const& prop) const;
std::vector<BT<std::string>> const& GetDirectoryEntries() const;
std::vector<BT<std::string>> const& GetFileEntries() const;
std::vector<std::unique_ptr<TargetPropertyEntry>> GetSources(
cm::GenEx::Context const& context, cmGeneratorTarget const* target,
cmGeneratorExpressionDAGChecker* dagChecker = nullptr) const;
// returned value:
// first: list of directories
// second: is context sensitive
std::pair<std::vector<std::string>, bool> GetDirectories(
cm::GenEx::Context const& context, cmGeneratorTarget const* target,
cmGeneratorExpressionDAGChecker* dagChecker = nullptr) const;
// returned value:
// first: list of files per directory
// second: is context sensitive
std::pair<std::map<std::string, std::vector<std::string>>, bool> GetFiles(
cm::GenEx::Context const& context, cmGeneratorTarget const* target,
cmGeneratorExpressionDAGChecker* dagChecker = nullptr) const;
std::vector<std::unique_ptr<cmCompiledGeneratorExpression>> const&
CompileFileEntries() const;
std::vector<std::unique_ptr<cmCompiledGeneratorExpression>> const&
CompileDirectoryEntries() const;
std::vector<std::string> EvaluateDirectoryEntries(
std::vector<std::unique_ptr<cmCompiledGeneratorExpression>> const& cges,
cm::GenEx::Context const& context, cmGeneratorTarget const* target,
cmGeneratorExpressionDAGChecker* dagChecker = nullptr) const;
void EvaluateFileEntry(
std::vector<std::string> const& dirs,
std::map<std::string, std::vector<std::string>>& filesPerDir,
std::unique_ptr<cmCompiledGeneratorExpression> const& cge,
cm::GenEx::Context const& context, cmGeneratorTarget const* target,
cmGeneratorExpressionDAGChecker* dagChecker = nullptr) const;
private:
cmFileSet const* FileSet;
mutable std::vector<std::unique_ptr<cmCompiledGeneratorExpression>>
CompiledDirectoryEntries;
mutable std::vector<std::unique_ptr<cmCompiledGeneratorExpression>>
CompiledFileEntries;
};
+160
View File
@@ -0,0 +1,160 @@
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
file LICENSE.rst or https://cmake.org/licensing for details. */
#include "cmGeneratorFileSets.h"
#include <algorithm>
#include <iterator>
#include <map>
#include <utility>
#include <vector>
#include <cm/memory>
#include "cmGenExContext.h"
#include "cmGeneratorFileSet.h"
#include "cmGeneratorTarget.h"
#include "cmSourceFile.h"
#include "cmSystemTools.h"
#include "cmTarget.h"
cmGeneratorFileSets::cmGeneratorFileSets(cmGeneratorTarget* target,
cmLocalGenerator* lg)
: Target(target)
, LocalGenerator(lg)
{
for (auto const& name : target->Target->GetAllFileSetNames()) {
auto entry = this->FileSets.emplace(
name,
cm::make_unique<cmGeneratorFileSet>(target->Target->GetFileSet(name)));
auto const* fileSet = entry.first->second.get();
this->AllFileSets.push_back(fileSet);
if (fileSet->IsForSelf()) {
this->SelfFileSets[fileSet->GetType()].push_back(fileSet);
}
if (fileSet->IsForInterface()) {
this->InterfaceFileSets[fileSet->GetType()].push_back(fileSet);
}
}
}
cmGeneratorFileSets::~cmGeneratorFileSets() = default;
std::vector<cmGeneratorFileSet const*> const&
cmGeneratorFileSets::GetAllFileSets() const
{
return this->AllFileSets;
}
namespace {
std::vector<cmGeneratorFileSet const*> NoFileSets;
}
std::vector<cmGeneratorFileSet const*> const& cmGeneratorFileSets::GetFileSets(
cm::string_view type) const
{
auto it = this->SelfFileSets.find(type);
if (it != this->SelfFileSets.end()) {
return it->second;
}
return NoFileSets;
}
std::vector<cmGeneratorFileSet const*> const&
cmGeneratorFileSets::GetInterfaceFileSets(cm::string_view type) const
{
auto it = this->InterfaceFileSets.find(type);
if (it != this->InterfaceFileSets.end()) {
return it->second;
}
return NoFileSets;
}
cmGeneratorFileSet const* cmGeneratorFileSets::GetFileSet(
std::string const& name) const
{
auto const it = this->FileSets.find(name);
if (it != this->FileSets.end()) {
return it->second.get();
}
return nullptr;
}
cmGeneratorFileSet const* cmGeneratorFileSets::GetFileSetForSource(
std::string const& config, std::string const& path) const
{
this->BuildInfoCache(config);
auto const& info = this->Configs[config];
auto const it = info.FileSetCache.find(path);
if (it == info.FileSetCache.end()) {
return nullptr;
}
return it->second;
}
cmGeneratorFileSet const* cmGeneratorFileSets::GetFileSetForSource(
std::string const& config, cmSourceFile const* sf) const
{
return this->GetFileSetForSource(config, sf->GetFullPath());
}
std::vector<std::unique_ptr<cm::TargetPropertyEntry>>
cmGeneratorFileSets::GetSources(
cm::GenEx::Context const& context, cmGeneratorTarget const* target,
cmGeneratorExpressionDAGChecker* dagChecker) const
{
std::vector<std::unique_ptr<TargetPropertyEntry>> entries;
for (auto const& entry : this->FileSets) {
auto const* fileSet = entry.second.get();
if (fileSet->IsForSelf()) {
auto sources = fileSet->GetSources(context, target, dagChecker);
std::move(sources.begin(), sources.end(), std::back_inserter(entries));
}
}
return entries;
}
std::vector<std::unique_ptr<cm::TargetPropertyEntry>>
cmGeneratorFileSets::GetSources(
std::string type, cm::GenEx::Context const& context,
cmGeneratorTarget const* target,
cmGeneratorExpressionDAGChecker* dagChecker) const
{
std::vector<std::unique_ptr<TargetPropertyEntry>> entries;
for (auto const& entry : this->FileSets) {
auto const* fileSet = entry.second.get();
if (!fileSet->IsForSelf() && fileSet->GetType() == type) {
auto sources = fileSet->GetSources(context, target, dagChecker);
std::move(sources.begin(), sources.end(), std::back_inserter(entries));
}
}
return entries;
}
void cmGeneratorFileSets::BuildInfoCache(std::string const& config) const
{
auto& info = this->Configs[config];
if (info.BuiltCache) {
return;
}
for (auto const& item : this->FileSets) {
cm::GenEx::Context context(this->LocalGenerator, config);
auto const* file_set = item.second.get();
auto files = file_set->GetFiles(context, this->Target);
for (auto const& it : files.first) {
for (auto const& filename : it.second) {
auto collapsedFile = cmSystemTools::CollapseFullPath(filename);
info.FileSetCache[collapsedFile] = file_set;
}
}
}
info.BuiltCache = true;
}
+86
View File
@@ -0,0 +1,86 @@
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
file LICENSE.rst or https://cmake.org/licensing for details. */
#pragma once
#include "cmConfigure.h" // IWYU pragma: keep
#include <map>
#include <memory>
#include <string>
#include <unordered_map>
#include <vector>
#include <cm/string_view>
#include "cmTargetPropertyEntry.h"
namespace cm {
namespace GenEx {
struct Context;
}
}
struct cmGeneratorExpressionDAGChecker;
class cmSourceFile;
class cmGeneratorTarget;
class cmGeneratorFileSet;
class cmLocalGenerator;
class cmGeneratorFileSets
{
public:
using TargetPropertyEntry = cm::TargetPropertyEntry;
cmGeneratorFileSets(cmGeneratorTarget* target, cmLocalGenerator* lg);
~cmGeneratorFileSets();
cmGeneratorFileSets(cmGeneratorFileSets const&) = delete;
cmGeneratorFileSets& operator=(cmGeneratorFileSets const&) = delete;
bool Empty() const { return this->FileSets.empty(); }
std::vector<cmGeneratorFileSet const*> const& GetAllFileSets() const;
std::vector<cmGeneratorFileSet const*> const& GetFileSets(
cm::string_view type) const;
std::vector<cmGeneratorFileSet const*> const& GetInterfaceFileSets(
cm::string_view type) const;
cmGeneratorFileSet const* GetFileSet(std::string const& name) const;
cmGeneratorFileSet const* GetFileSetForSource(std::string const& config,
std::string const& file) const;
cmGeneratorFileSet const* GetFileSetForSource(std::string const& config,
cmSourceFile const* sf) const;
std::vector<std::unique_ptr<TargetPropertyEntry>> GetSources(
cm::GenEx::Context const& context, cmGeneratorTarget const* target,
cmGeneratorExpressionDAGChecker* dagChecker = nullptr) const;
std::vector<std::unique_ptr<TargetPropertyEntry>> GetSources(
std::string type, cm::GenEx::Context const& context,
cmGeneratorTarget const* target,
cmGeneratorExpressionDAGChecker* dagChecker = nullptr) const;
private:
// file sets indexed by name
std::map<std::string, std::unique_ptr<cmGeneratorFileSet>> FileSets;
std::vector<cmGeneratorFileSet const*> AllFileSets;
// list of private file sets indexed by type
std::unordered_map<cm::string_view, std::vector<cmGeneratorFileSet const*>>
SelfFileSets;
// list of interface file sets indexed by type
std::unordered_map<cm::string_view, std::vector<cmGeneratorFileSet const*>>
InterfaceFileSets;
struct InfoByConfig
{
bool BuiltCache = false;
std::map<std::string, cmGeneratorFileSet const*> FileSetCache;
};
mutable std::map<std::string, InfoByConfig> Configs;
void BuildInfoCache(std::string const& config) const;
cmGeneratorTarget* Target;
cmLocalGenerator* LocalGenerator;
};
+66 -111
View File
@@ -28,11 +28,14 @@
#include "cmCxxModuleUsageEffects.h"
#include "cmExperimental.h"
#include "cmFileSet.h"
#include "cmFileSetMetadata.h"
#include "cmFileTimes.h"
#include "cmGenExContext.h"
#include "cmGeneratedFileStream.h"
#include "cmGeneratorExpression.h"
#include "cmGeneratorExpressionDAGChecker.h"
#include "cmGeneratorFileSet.h"
#include "cmGeneratorFileSets.h"
#include "cmGeneratorOptions.h"
#include "cmGlobalGenerator.h"
#include "cmList.h"
@@ -90,6 +93,7 @@ static void CreatePropertyGeneratorExpressions(
cmGeneratorTarget::cmGeneratorTarget(cmTarget* t, cmLocalGenerator* lg)
: Target(t)
, FileSets(cm::make_unique<cmGeneratorFileSets>(this, lg))
{
this->Makefile = this->Target->GetMakefile();
this->LocalGenerator = lg;
@@ -1122,8 +1126,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->GetFileSetsEntries(cmFileSet::HEADERS).empty() ||
!this->Target->GetFileSetsEntries(cmFileSet::CXX_MODULES).empty()) {
!this->GetFileSets(cm::FileSetMetadata::HEADERS).empty() ||
!this->GetFileSets(cm::FileSetMetadata::CXX_MODULES).empty()) {
return true;
}
break;
@@ -2342,7 +2346,7 @@ cmGeneratorTarget::GetClassifiedFlagsForSource(cmSourceFile const* sf,
std::string bmiFlags;
auto const* fs = this->GetFileSetForSource(config, sf);
if (fs && fs->GetType() == cmFileSet::CXX_MODULES) {
if (fs && fs->GetType() == cm::FileSetMetadata::CXX_MODULES) {
if (lang != "CXX"_s) {
mf->IssueMessage(
MessageType::FATAL_ERROR,
@@ -5369,21 +5373,13 @@ bool cmGeneratorTarget::DiscoverSyntheticTargets(
// Copy file sets.
{
auto fsNames = model->GetAllFileSetNames();
for (auto const& fsName : fsNames) {
auto const* fs = model->GetFileSet(fsName);
if (!fs) {
mf->IssueMessage(MessageType::INTERNAL_ERROR,
cmStrCat("Failed to find file set named '",
fsName, "' on target '", tgt->GetName(),
'\''));
continue;
}
auto* newFs = tgt
->GetOrCreateFileSet(fs->GetName(), fs->GetType(),
fs->GetVisibility())
.first;
newFs->CopyEntries(fs);
for (auto const* gfs : gt->GetAllFileSets()) {
auto* newFs =
tgt
->GetOrCreateFileSet(gfs->GetName(), gfs->GetType(),
cm::FileSetMetadata::Visibility::Public)
.first;
newFs->CopyEntries(gfs->GetFileSet());
}
}
@@ -5782,16 +5778,14 @@ bool cmGeneratorTarget::AddHeaderSetVerification()
allVerifyTargetName, { cmStateEnums::TargetDomain::NATIVE });
auto fileSetEntries = isInterface
? this->Target->GetInterfaceFileSetsEntries(cmFileSet::HEADERS)
: this->Target->GetFileSetsEntries(cmFileSet::HEADERS);
? this->GetInterfaceFileSets(cm::FileSetMetadata::HEADERS)
: this->GetFileSets(cm::FileSetMetadata::HEADERS);
std::set<cmFileSet*> fileSets;
for (auto const& entry : fileSetEntries) {
for (auto const& name : cmList{ entry.Value }) {
if (all || verifySet.count(name)) {
fileSets.insert(this->Target->GetFileSet(name));
verifySet.erase(name);
}
std::set<cmGeneratorFileSet const*> fileSets;
for (auto const& fileSet : fileSetEntries) {
if (all || verifySet.count(fileSet->GetName())) {
fileSets.insert(fileSet);
verifySet.erase(fileSet->GetName());
}
}
@@ -5828,9 +5822,9 @@ bool cmGeneratorTarget::AddHeaderSetVerification()
}
cm::optional<std::set<std::string>> languages;
for (auto* fileSet : fileSets) {
auto dirCges = fileSet->CompileDirectoryEntries();
auto fileCges = fileSet->CompileFileEntries();
for (auto const* fileSet : fileSets) {
auto const& dirCges = fileSet->CompileDirectoryEntries();
auto const& fileCges = fileSet->CompileFileEntries();
static auto const contextSensitive =
[](std::unique_ptr<cmCompiledGeneratorExpression> const& cge) {
@@ -6143,28 +6137,14 @@ bool cmGeneratorTarget::HaveFortranSources() const
return have_direct || have_via_target_objects;
}
bool cmGeneratorTarget::HaveCxx20ModuleSources(std::string* errorMessage) const
bool cmGeneratorTarget::HaveCxx20ModuleSources() const
{
auto const& fs_names = this->Target->GetAllFileSetNames();
return std::any_of(
fs_names.begin(), fs_names.end(),
[this, errorMessage](std::string const& name) -> bool {
auto const* file_set = this->Target->GetFileSet(name);
if (!file_set) {
auto message = cmStrCat("Target \"", this->Target->GetName(),
"\" is tracked to have file set \"", name,
"\", but it was not found.");
if (errorMessage) {
*errorMessage = std::move(message);
} else {
this->Makefile->IssueMessage(MessageType::INTERNAL_ERROR, message);
}
return false;
}
auto const& fs_type = file_set->GetType();
return fs_type == cmFileSet::CXX_MODULES;
});
auto const& fileSets = this->GetAllFileSets();
return std::any_of(fileSets.begin(), fileSets.end(),
[](cmGeneratorFileSet const* file_set) -> bool {
auto const& fs_type = file_set->GetType();
return fs_type == cm::FileSetMetadata::CXX_MODULES;
});
}
cmGeneratorTarget::Cxx20SupportLevel cmGeneratorTarget::HaveCxxModuleSupport(
@@ -6306,21 +6286,6 @@ bool cmGeneratorTarget::NeedDyndep(std::string const& lang,
return lang == "Fortran"_s || this->NeedCxxModuleSupport(lang, config);
}
cmFileSet const* cmGeneratorTarget::GetFileSetForSource(
std::string const& config, cmSourceFile const* sf) const
{
this->BuildFileSetInfoCache(config);
auto const& path = sf->GetFullPath();
auto const& per_config = this->Configs[config];
auto const fsit = per_config.FileSetCache.find(path);
if (fsit == per_config.FileSetCache.end()) {
return nullptr;
}
return fsit->second;
}
bool cmGeneratorTarget::NeedDyndepForSource(std::string const& lang,
std::string const& config,
cmSourceFile const* sf) const
@@ -6337,7 +6302,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() == cmFileSet::CXX_MODULES) {
if (fs && fs->GetType() == cm::FileSetMetadata::CXX_MODULES) {
return true;
}
@@ -6395,6 +6360,40 @@ cmGeneratorTarget::CxxModuleSupport cmGeneratorTarget::NeedCxxDyndep(
return policyAnswer;
}
bool cmGeneratorTarget::HasFileSets() const
{
return !this->FileSets->Empty();
}
std::vector<cmGeneratorFileSet const*> const&
cmGeneratorTarget::GetAllFileSets() const
{
return this->FileSets->GetAllFileSets();
}
std::vector<cmGeneratorFileSet const*> const& cmGeneratorTarget::GetFileSets(
cm::string_view type) const
{
return this->FileSets->GetFileSets(type);
}
std::vector<cmGeneratorFileSet const*> const&
cmGeneratorTarget::GetInterfaceFileSets(cm::string_view type) const
{
return this->FileSets->GetInterfaceFileSets(type);
}
cmGeneratorFileSet const* cmGeneratorTarget::GetFileSet(
std::string const& name) const
{
return this->FileSets->GetFileSet(name);
}
cmGeneratorFileSet const* cmGeneratorTarget::GetFileSetForSource(
std::string const& config, cmSourceFile const* sf) const
{
return this->FileSets->GetFileSetForSource(config, sf);
}
std::string cmGeneratorTarget::BuildDatabasePath(
std::string const& lang, std::string const& config) const
{
@@ -6420,50 +6419,6 @@ std::string cmGeneratorTarget::BuildDatabasePath(
"_build_database.json");
}
void cmGeneratorTarget::BuildFileSetInfoCache(std::string const& config) const
{
auto& per_config = this->Configs[config];
if (per_config.BuiltFileSetCache) {
return;
}
auto const* tgt = this->Target;
for (auto const& name : tgt->GetAllFileSetNames()) {
auto const* file_set = tgt->GetFileSet(name);
if (!file_set) {
tgt->GetMakefile()->IssueMessage(
MessageType::INTERNAL_ERROR,
cmStrCat("Target \"", tgt->GetName(),
"\" is tracked to have file set \"", name,
"\", but it was not found."));
continue;
}
cm::GenEx::Context context(this->LocalGenerator, config);
auto fileEntries = file_set->CompileFileEntries();
auto directoryEntries = file_set->CompileDirectoryEntries();
auto directories =
file_set->EvaluateDirectoryEntries(directoryEntries, context, this);
std::map<std::string, std::vector<std::string>> files;
for (auto const& entry : fileEntries) {
file_set->EvaluateFileEntry(directories, files, entry, context, this);
}
for (auto const& it : files) {
for (auto const& filename : it.second) {
auto collapsedFile = cmSystemTools::CollapseFullPath(filename);
per_config.FileSetCache[collapsedFile] = file_set;
}
}
}
per_config.BuiltFileSetCache = true;
}
std::string cmGeneratorTarget::GetSwiftModuleName() const
{
return this->GetPropertyOrDefault("Swift_MODULE_NAME", this->GetName());
+17 -12
View File
@@ -37,12 +37,11 @@ struct Evaluation;
}
}
class cmake;
enum class cmBuildStep;
class cmCompiledGeneratorExpression;
class cmComputeLinkInformation;
class cmCustomCommand;
class cmFileSet;
class cmGeneratorFileSets;
class cmGeneratorFileSet;
class cmGlobalGenerator;
class cmLocalGenerator;
class cmMakefile;
@@ -1500,6 +1499,18 @@ public:
bool HaveFortranSources() const;
bool HaveFortranSources(std::string const& config) const;
// File sets support queries
bool HasFileSets() const;
std::vector<cmGeneratorFileSet const*> const& GetAllFileSets() const;
std::vector<cmGeneratorFileSet const*> const& GetFileSets(
cm::string_view type) const;
std::vector<cmGeneratorFileSet const*> const& GetInterfaceFileSets(
cm::string_view type) const;
cmGeneratorFileSet const* GetFileSet(std::string const& name) const;
cmGeneratorFileSet const* GetFileSetForSource(std::string const& config,
cmSourceFile const* sf) const;
// C++20 module support queries.
/**
@@ -1507,11 +1518,8 @@ public:
*
* This will inspect the target itself to see if C++20 module
* support is expected to work based on its sources.
*
* If `errorMessage` is given a non-`nullptr`, any error message will be
* stored in it, otherwise the error will be reported directly.
*/
bool HaveCxx20ModuleSources(std::string* errorMessage = nullptr) const;
bool HaveCxx20ModuleSources() const;
enum class Cxx20SupportLevel
{
@@ -1524,6 +1532,7 @@ public:
// C++20 modules are available and working.
Supported,
};
/**
* Query whether the target has C++20 module support available (regardless of
* whether it is required or not).
@@ -1536,8 +1545,6 @@ public:
bool NeedCxxModuleSupport(std::string const& lang,
std::string const& config) const;
bool NeedDyndep(std::string const& lang, std::string const& config) const;
cmFileSet const* GetFileSetForSource(std::string const& config,
cmSourceFile const* sf) const;
bool NeedDyndepForSource(std::string const& lang, std::string const& config,
cmSourceFile const* sf) const;
enum class CxxModuleSupport
@@ -1563,16 +1570,14 @@ public:
static MsvcCharSet GetMsvcCharSet(std::string const& singleDefine);
private:
void BuildFileSetInfoCache(std::string const& config) const;
struct InfoByConfig
{
bool BuiltFileSetCache = false;
std::map<std::string, cmFileSet const*> FileSetCache;
std::map<cmGeneratorTarget const*, std::vector<cmGeneratorTarget const*>>
SyntheticDeps;
std::map<cmSourceFile const*, ClassifiedFlags> SourceFlags;
};
mutable std::map<std::string, InfoByConfig> Configs;
std::unique_ptr<cmGeneratorFileSets> FileSets;
bool PchReused = false;
mutable bool ComputingPchReuse = false;
mutable bool PchReuseCycleDetected = false;
+42 -81
View File
@@ -5,6 +5,7 @@
/* clang-format on */
#include <cstddef>
#include <functional>
#include <map>
#include <memory>
#include <set>
@@ -16,15 +17,16 @@
#include <cm/string_view>
#include <cmext/algorithm>
#include <cmext/string_view>
#include "cmsys/RegularExpression.hxx"
#include "cmEvaluatedTargetProperty.h"
#include "cmFileSet.h"
#include "cmFileSetMetadata.h"
#include "cmGenExContext.h"
#include "cmGeneratorExpression.h"
#include "cmGeneratorExpressionDAGChecker.h"
#include "cmGeneratorFileSet.h"
#include "cmGeneratorFileSets.h"
#include "cmGlobalGenerator.h"
#include "cmLinkItem.h"
#include "cmList.h"
@@ -80,92 +82,23 @@ void AddObjectEntries(cmGeneratorTarget const* headTarget,
}
}
void addFileSetEntry(cmGeneratorTarget const* headTarget,
cm::GenEx::Context const& context,
cmGeneratorExpressionDAGChecker* dagChecker,
cmFileSet const* fileSet,
EvaluatedTargetPropertyEntries& entries)
{
auto dirCges = fileSet->CompileDirectoryEntries();
auto dirs = fileSet->EvaluateDirectoryEntries(dirCges, context, headTarget,
dagChecker);
bool contextSensitiveDirs = false;
for (auto const& dirCge : dirCges) {
if (dirCge->GetHadContextSensitiveCondition()) {
contextSensitiveDirs = true;
break;
}
}
cmake* cm = headTarget->GetLocalGenerator()->GetCMakeInstance();
for (auto& entryCge : fileSet->CompileFileEntries()) {
auto targetPropEntry = cm::TargetPropertyEntry::CreateFileSet(
dirs, contextSensitiveDirs, std::move(entryCge), fileSet);
entries.Entries.emplace_back(EvaluateTargetPropertyEntry(
headTarget, context, dagChecker, *targetPropEntry));
EvaluatedTargetPropertyEntry const& entry = entries.Entries.back();
for (auto const& file : entry.Values) {
auto* sf = headTarget->Makefile->GetOrCreateSource(file);
if (fileSet->GetType() == cmFileSet::HEADERS) {
sf->SetProperty("HEADER_FILE_ONLY", "TRUE");
}
#ifndef CMAKE_BOOTSTRAP
std::string e;
std::string w;
auto path = sf->ResolveFullPath(&e, &w);
if (!w.empty()) {
cm->IssueMessage(MessageType::AUTHOR_WARNING, w, entry.Backtrace);
}
if (path.empty()) {
if (!e.empty()) {
cm->IssueMessage(MessageType::FATAL_ERROR, e, entry.Backtrace);
}
return;
}
bool found = false;
for (auto const& sg : headTarget->Makefile->GetSourceGroups()) {
if (sg->MatchChildrenFiles(path)) {
found = true;
break;
}
}
if (!found) {
if (fileSet->GetType() == cmFileSet::HEADERS) {
headTarget->Makefile->GetOrCreateSourceGroup("Header Files")
->AddGroupFile(path);
}
}
#endif
}
}
}
void AddFileSetEntries(cmGeneratorTarget const* headTarget,
cmGeneratorFileSets const* fileSets,
cm::GenEx::Context const& context,
cmGeneratorExpressionDAGChecker* dagChecker,
EvaluatedTargetPropertyEntries& entries)
{
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->GetFileSetsEntries(cmFileSet::CXX_MODULES)) {
for (auto const& name : cmList{ entry.Value }) {
auto const* cxxModuleSet = headTarget->Target->GetFileSet(name);
addFileSetEntry(headTarget, context, dagChecker, cxxModuleSet, entries);
}
}
auto sources = fileSets->GetSources(context, headTarget, dagChecker);
entries =
EvaluateTargetPropertyEntries(headTarget, context, dagChecker, sources);
}
bool processSources(cmGeneratorTarget const* tgt,
EvaluatedTargetPropertyEntries& entries,
std::vector<BT<std::string>>& srcs,
std::unordered_set<std::string>& uniqueSrcs,
bool debugSources)
bool debugSources,
std::function<void(cmSourceFile*)> postProcess = {})
{
cmMakefile* mf = tgt->Target->GetMakefile();
@@ -210,6 +143,10 @@ bool processSources(cmGeneratorTarget const* tgt,
return contextDependent;
}
src = fullPath;
if (postProcess) {
postProcess(sf);
}
}
std::string usedSources;
for (std::string const& src : entry.Values) {
@@ -281,9 +218,33 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetSourceFilePaths(
// Collect this target's file sets.
EvaluatedTargetPropertyEntries fileSetEntries;
AddFileSetEntries(this, context, &dagChecker, fileSetEntries);
AddFileSetEntries(this, this->FileSets.get(), context, &dagChecker,
fileSetEntries);
auto processFileSetEntry = [this, &config](cmSourceFile* sf) {
auto const* fileSet = this->GetFileSetForSource(config, sf);
if (fileSet->GetType() == cm::FileSetMetadata::HEADERS) {
sf->SetProperty("HEADER_FILE_ONLY", "TRUE");
}
#if !defined(CMAKE_BOOTSTRAP)
cmMakefile* mf = this->Target->GetMakefile();
auto const& path = sf->GetFullPath();
bool found = false;
for (auto const& sg : mf->GetSourceGroups()) {
if (sg->MatchChildrenFiles(path)) {
found = true;
break;
}
}
if (!found) {
if (fileSet->GetType() == cm::FileSetMetadata::HEADERS) {
mf->GetOrCreateSourceGroup("Header Files")->AddGroupFile(path);
}
}
#endif
};
bool contextDependentFileSets =
processSources(this, fileSetEntries, files, uniqueSrcs, debugSources);
processSources(this, fileSetEntries, files, uniqueSrcs, debugSources,
processFileSetEntry);
// Determine if sources are context-dependent or not.
if (!contextDependentDirectSources && !contextDependentInterfaceSources &&
@@ -397,11 +358,11 @@ void cmGeneratorTarget::ComputeKindedSources(KindedSources& files,
// Compute the kind (classification) of this source file.
SourceKind kind;
std::string ext = cmSystemTools::LowerCase(sf->GetExtension());
cmFileSet const* fs = this->GetFileSetForSource(config, sf);
cmGeneratorFileSet const* fs = this->GetFileSetForSource(config, sf);
if (sf->GetCustomCommand()) {
kind = SourceKindCustomCommand;
} else if (!this->Target->IsNormal() && !this->Target->IsImported() &&
fs && (fs->GetType() == cmFileSet::CXX_MODULES)) {
fs && (fs->GetType() == cm::FileSetMetadata::CXX_MODULES)) {
kind = SourceKindCxxModuleSource;
} else if (this->Target->GetType() == cmStateEnums::UTILITY ||
this->Target->GetType() == cmStateEnums::INTERFACE_LIBRARY
+6 -18
View File
@@ -9,11 +9,11 @@
#include <vector>
#include <cm/string_view>
#include <cmext/string_view>
#include "cmFileSet.h"
#include "cmFileSetMetadata.h"
#include "cmGenExContext.h"
#include "cmGeneratorExpression.h"
#include "cmGeneratorFileSet.h"
#include "cmGeneratorTarget.h"
#include "cmGlobalGenerator.h"
#include "cmInstallType.h"
@@ -54,8 +54,7 @@ bool cmInstallFileSetGenerator::Compute(cmLocalGenerator* lg)
lg->GetGlobalGenerator()->FindGeneratorTarget(this->TargetName);
}
auto const& target = *this->Target->Target;
this->FileSet = target.GetFileSet(this->FileSetName);
this->FileSet = this->Target->GetFileSet(this->FileSetName);
if (!this->FileSet) {
// No file set of the given name was ever provided for this target, nothing
@@ -63,12 +62,13 @@ bool cmInstallFileSetGenerator::Compute(cmLocalGenerator* lg)
return true;
}
auto const& target = *this->Target->Target;
cmList interfaceFileSetEntries{ target.GetSafeProperty(
target.GetInterfaceFileSetsPropertyName(this->FileSet->GetType())) };
if (std::find(interfaceFileSetEntries.begin(), interfaceFileSetEntries.end(),
this->FileSetName) != interfaceFileSetEntries.end()) {
if (this->FileSet->GetType() == cmFileSet::HEADERS) {
if (this->FileSet->GetType() == cm::FileSetMetadata::HEADERS) {
this->Destination = this->FileSetDestinations.Headers;
} else {
this->Destination = this->FileSetDestinations.CXXModules;
@@ -121,19 +121,7 @@ std::map<std::string, std::vector<std::string>>
cmInstallFileSetGenerator::CalculateFilesPerDir(
std::string const& config) const
{
std::map<std::string, std::vector<std::string>> result;
cm::GenEx::Context context(this->LocalGenerator, config);
auto dirCges = this->FileSet->CompileDirectoryEntries();
auto dirs =
this->FileSet->EvaluateDirectoryEntries(dirCges, context, this->Target);
auto fileCges = this->FileSet->CompileFileEntries();
for (auto const& fileCge : fileCges) {
this->FileSet->EvaluateFileEntry(dirs, result, fileCge, context,
this->Target);
}
return result;
return this->FileSet->GetFiles(context, this->Target).first;
}
+3 -3
View File
@@ -10,7 +10,7 @@
#include "cmInstallGenerator.h"
class cmGeneratorTarget;
class cmFileSet;
class cmGeneratorFileSet;
class cmListFileBacktrace;
class cmLocalGenerator;
@@ -38,7 +38,7 @@ public:
std::string GetDestination() const { return this->Destination; }
bool GetOptional() const { return this->Optional; }
std::string GetFileSetName() const { return this->FileSetName; }
cmFileSet const* GetFileSet() const { return this->FileSet; };
cmGeneratorFileSet const* GetFileSet() const { return this->FileSet; };
cmGeneratorTarget* GetTarget() const { return this->Target; }
protected:
@@ -48,7 +48,7 @@ protected:
private:
std::string TargetName;
cmLocalGenerator* LocalGenerator;
cmFileSet const* FileSet;
cmGeneratorFileSet const* FileSet;
std::string const FileSetName;
std::string const FilePermissions;
cmFileSetDestinations FileSetDestinations;
+5 -24
View File
@@ -24,10 +24,11 @@
#include "cmComputeLinkInformation.h"
#include "cmCustomCommand.h"
#include "cmCustomCommandGenerator.h"
#include "cmFileSet.h"
#include "cmFileSetMetadata.h"
#include "cmGenExContext.h"
#include "cmGeneratedFileStream.h"
#include "cmGeneratorExpression.h"
#include "cmGeneratorFileSet.h"
#include "cmGeneratorOptions.h"
#include "cmGeneratorTarget.h"
#include "cmGlobalUnixMakefileGenerator3.h"
@@ -347,28 +348,8 @@ void cmMakefileTargetGenerator::WriteTargetBuildRules()
std::map<std::string, std::string> file_set_map;
auto const* tgt = this->GeneratorTarget->Target;
for (auto const& name : tgt->GetAllFileSetNames()) {
auto const* file_set = tgt->GetFileSet(name);
if (!file_set) {
this->Makefile->IssueMessage(
MessageType::INTERNAL_ERROR,
cmStrCat("Target \"", tgt->GetName(),
"\" is tracked to have file set \"", name,
"\", but it was not found."));
continue;
}
auto fileEntries = file_set->CompileFileEntries();
auto directoryEntries = file_set->CompileDirectoryEntries();
auto directories = file_set->EvaluateDirectoryEntries(
directoryEntries, context, this->GeneratorTarget);
std::map<std::string, std::vector<std::string>> files;
for (auto const& entry : fileEntries) {
file_set->EvaluateFileEntry(directories, files, entry, context,
this->GeneratorTarget);
}
for (auto const* file_set : this->GeneratorTarget->GetAllFileSets()) {
auto files = file_set->GetFiles(context, this->GeneratorTarget).first;
for (auto const& it : files) {
for (auto const& filename : it.second) {
file_set_map[filename] = file_set->GetType();
@@ -394,7 +375,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 == cmFileSet::CXX_MODULES) {
if (file_set_type == cm::FileSetMetadata::CXX_MODULES) {
if (sf->GetLanguage() != "CXX"_s) {
this->Makefile->IssueMessage(
MessageType::FATAL_ERROR,
+10 -11
View File
@@ -27,9 +27,10 @@
#include "cmCustomCommand.h"
#include "cmCustomCommandGenerator.h"
#include "cmDyndepCollation.h"
#include "cmFileSet.h"
#include "cmFileSetMetadata.h"
#include "cmGeneratedFileStream.h"
#include "cmGeneratorExpression.h"
#include "cmGeneratorFileSet.h"
#include "cmGeneratorOptions.h"
#include "cmGeneratorTarget.h"
#include "cmGlobalCommonGenerator.h"
@@ -254,7 +255,7 @@ std::string cmNinjaTargetGenerator::ComputeFlagsForObject(
}
auto const* fs = this->GeneratorTarget->GetFileSetForSource(config, source);
if (fs && fs->GetType() == cmFileSet::CXX_MODULES) {
if (fs && fs->GetType() == cm::FileSetMetadata::CXX_MODULES) {
if (source->GetLanguage() != "CXX"_s) {
this->GetMakefile()->IssueMessage(
MessageType::FATAL_ERROR,
@@ -1030,7 +1031,7 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatements(
std::vector<std::string> ccouts;
std::vector<std::string> ccouts_private;
bool usePrivateGeneratedSources = false;
if (this->GeneratorTarget->Target->HasFileSets()) {
if (this->GeneratorTarget->HasFileSets()) {
switch (this->GetGeneratorTarget()->GetPolicyStatusCMP0154()) {
case cmPolicies::WARN:
case cmPolicies::OLD:
@@ -1052,13 +1053,11 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatements(
// Skip over outputs that were already detected.
std::advance(it, nPreviousOutputs);
while (it != ccouts.end()) {
cmFileSet const* fileset =
cmGeneratorFileSet const* fileset =
this->GeneratorTarget->GetFileSetForSource(
config, this->Makefile->GetOrCreateGeneratedSource(*it));
bool isVisible = fileset &&
cmFileSet::VisibilityIsForInterface(fileset->GetVisibility());
bool isIncludeable =
!fileset || cmFileSet::TypeCanBeIncluded(fileset->GetType());
bool isVisible = fileset && fileset->IsForInterface();
bool isIncludeable = !fileset || fileset->CanBeIncluded();
if (fileset && isVisible && isIncludeable) {
++it;
continue;
@@ -1164,12 +1163,12 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatements(
std::vector<cmSourceFile*> sources;
this->GeneratorTarget->GetSourceFiles(sources, config);
for (cmSourceFile const* sf : sources) {
cmFileSet const* fs =
cmGeneratorFileSet const* fs =
this->GeneratorTarget->GetFileSetForSource(config, sf);
if (!fs) {
continue;
}
if (fs->GetType() != cmFileSet::CXX_MODULES) {
if (fs->GetType() != cm::FileSetMetadata::CXX_MODULES) {
continue;
}
if (sf->GetLanguage().empty()) {
@@ -1177,7 +1176,7 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatements(
MessageType::FATAL_ERROR,
cmStrCat("Target \"", this->GeneratorTarget->GetName(),
"\" has source file\n ", sf->GetFullPath(),
"\nin a \"FILE_SET TYPE ", cmFileSet::CXX_MODULES,
"\nin a \"FILE_SET TYPE ", cm::FileSetMetadata::CXX_MODULES,
"\" but it is not scheduled for compilation."));
}
}
+28 -25
View File
@@ -21,6 +21,7 @@
#include "cmAlgorithms.h"
#include "cmCustomCommand.h"
#include "cmFileSet.h"
#include "cmFileSetMetadata.h"
#include "cmFindPackageStack.h"
#include "cmGeneratorExpression.h"
#include "cmGlobalGenerator.h"
@@ -98,18 +99,18 @@ cmValue cmTargetPropertyComputer::GetSources<cmTarget>(cmTarget const* tgt)
namespace {
struct FileSetEntries
{
FileSetEntries(cm::static_string_view propertyName)
FileSetEntries(cm::string_view propertyName)
: PropertyName(propertyName)
{
}
cm::static_string_view const PropertyName;
cm::string_view const PropertyName;
std::vector<BT<std::string>> Entries;
};
struct FileSetType
{
FileSetType(cm::static_string_view typeName,
FileSetType(cm::string_view typeName,
cm::static_string_view defaultDirectoryProperty,
cm::static_string_view defaultPathProperty,
cm::static_string_view directoryPrefix,
@@ -131,7 +132,7 @@ struct FileSetType
{
}
cm::static_string_view const TypeName;
cm::string_view const TypeName;
cm::static_string_view const DefaultDirectoryProperty;
cm::static_string_view const DefaultPathProperty;
cm::static_string_view const DirectoryPrefix;
@@ -157,7 +158,7 @@ struct FileSetType
cmTargetInternals const* impl,
std::string const& prop) const;
void AddFileSet(std::string const& name, cmFileSet::Visibility vis,
void AddFileSet(std::string const& name, cm::FileSetMetadata::Visibility vis,
cmListFileBacktrace bt);
};
@@ -703,19 +704,19 @@ cmTargetInternals::cmTargetInternals()
"IMPORTED_CXX_MODULES_COMPILE_FEATURES"_s)
, ImportedCxxModulesCompileOptions("IMPORTED_CXX_MODULES_COMPILE_OPTIONS"_s)
, ImportedCxxModulesLinkLibraries("IMPORTED_CXX_MODULES_LINK_LIBRARIES"_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 } } }
}
, FileSetTypes{ { cm::FileSetMetadata::HEADERS,
{ cm::FileSetMetadata::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 } } },
{ cm::FileSetMetadata::CXX_MODULES,
{ cm::FileSetMetadata::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 } } } }
{
}
@@ -805,12 +806,13 @@ std::pair<bool, cmValue> FileSetType::ReadProperties(
}
void FileSetType::AddFileSet(std::string const& name,
cmFileSet::Visibility vis, cmListFileBacktrace bt)
cm::FileSetMetadata::Visibility vis,
cmListFileBacktrace bt)
{
if (cmFileSet::VisibilityIsForSelf(vis)) {
if (cm::FileSetMetadata::VisibilityIsForSelf(vis)) {
this->SelfEntries.Entries.emplace_back(name, bt);
}
if (cmFileSet::VisibilityIsForInterface(vis)) {
if (cm::FileSetMetadata::VisibilityIsForInterface(vis)) {
this->InterfaceEntries.Entries.emplace_back(name, std::move(bt));
}
}
@@ -1771,10 +1773,10 @@ void cmTarget::CopyCxxModulesEntries(cmTarget const* tgt)
// Copy the C++ module fileset entries from `tgt`'s `INTERFACE` to this
// target's `PRIVATE`.
auto& entries =
this->impl->FileSetTypes.at(cmFileSet::CXX_MODULES).SelfEntries.Entries;
auto& entries = this->impl->FileSetTypes.at(cm::FileSetMetadata::CXX_MODULES)
.SelfEntries.Entries;
entries.clear();
entries = tgt->impl->FileSetTypes.at(cmFileSet::CXX_MODULES)
entries = tgt->impl->FileSetTypes.at(cm::FileSetMetadata::CXX_MODULES)
.InterfaceEntries.Entries;
}
@@ -3154,7 +3156,8 @@ cmFileSet* cmTarget::GetFileSet(std::string const& name)
}
std::pair<cmFileSet*, bool> cmTarget::GetOrCreateFileSet(
std::string const& name, std::string const& type, cmFileSet::Visibility vis)
std::string const& name, std::string const& type,
cm::FileSetMetadata::Visibility vis)
{
auto result = this->impl->FileSets.emplace(
name, cmFileSet(this->GetMakefile(), name, type, vis));
+10 -4
View File
@@ -13,9 +13,9 @@
#include <vector>
#include <cm/optional>
#include <cm/string_view>
#include "cmAlgorithms.h"
#include "cmFileSet.h"
#include "cmListFileCache.h"
#include "cmPolicies.h"
#include "cmStateTypes.h"
@@ -23,6 +23,12 @@
#include "cmTargetLinkLibraryType.h"
#include "cmValue.h"
namespace cm {
namespace FileSetMetadata {
enum class Visibility;
}
}
class cmCustomCommand;
class cmFileSet;
class cmFindPackageStack;
@@ -344,9 +350,9 @@ public:
cmFileSet const* GetFileSet(std::string const& name) const;
cmFileSet* GetFileSet(std::string const& name);
std::pair<cmFileSet*, bool> GetOrCreateFileSet(std::string const& name,
std::string const& type,
cmFileSet::Visibility vis);
std::pair<cmFileSet*, bool> GetOrCreateFileSet(
std::string const& name, std::string const& type,
cm::FileSetMetadata::Visibility vis);
std::vector<std::string> GetAllFileSetNames() const;
std::vector<std::string> GetAllInterfaceFileSets() const;
-70
View File
@@ -3,17 +3,13 @@
#include "cmTargetPropertyEntry.h"
#include <map>
#include <string>
#include <utility>
#include <vector>
#include <cm/memory>
#include "cmFileSet.h"
#include "cmGeneratorExpression.h"
#include "cmLinkItem.h"
#include "cmList.h"
#include "cmListFileCache.h"
class cmake;
@@ -84,63 +80,6 @@ private:
std::unique_ptr<cmCompiledGeneratorExpression> const ge;
};
class TargetPropertyEntryFileSet : public TargetPropertyEntry
{
public:
TargetPropertyEntryFileSet(
std::vector<std::string> dirs, bool contextSensitiveDirs,
std::unique_ptr<cmCompiledGeneratorExpression> entryCge,
cmFileSet const* fileSet, cmLinkItem const& item = NoLinkItem)
: TargetPropertyEntry(item)
, BaseDirs(std::move(dirs))
, ContextSensitiveDirs(contextSensitiveDirs)
, EntryCge(std::move(entryCge))
, FileSet(fileSet)
{
}
std::string const& Evaluate(
cm::GenEx::Context const& context, cmGeneratorTarget const* headTarget,
cmGeneratorExpressionDAGChecker* dagChecker) const override
{
std::map<std::string, std::vector<std::string>> filesPerDir;
this->FileSet->EvaluateFileEntry(this->BaseDirs, filesPerDir,
this->EntryCge, context, headTarget,
dagChecker);
std::vector<std::string> files;
for (auto const& it : filesPerDir) {
files.insert(files.end(), it.second.begin(), it.second.end());
}
static std::string filesStr;
filesStr = cmList::to_string(files);
return filesStr;
}
cmListFileBacktrace GetBacktrace() const override
{
return this->EntryCge->GetBacktrace();
}
std::string const& GetInput() const override
{
return this->EntryCge->GetInput();
}
bool GetHadContextSensitiveCondition() const override
{
return this->ContextSensitiveDirs ||
this->EntryCge->GetHadContextSensitiveCondition();
}
private:
std::vector<std::string> const BaseDirs;
bool const ContextSensitiveDirs;
std::unique_ptr<cmCompiledGeneratorExpression> const EntryCge;
cmFileSet const* FileSet;
};
std::unique_ptr<TargetPropertyEntry> TargetPropertyEntry::Create(
cmake& cmakeInstance, const BT<std::string>& propertyValue,
bool evaluateForBuildsystem)
@@ -158,15 +97,6 @@ std::unique_ptr<TargetPropertyEntry> TargetPropertyEntry::Create(
cm::make_unique<TargetPropertyEntryString>(propertyValue));
}
std::unique_ptr<TargetPropertyEntry> TargetPropertyEntry::CreateFileSet(
std::vector<std::string> dirs, bool contextSensitiveDirs,
std::unique_ptr<cmCompiledGeneratorExpression> entryCge,
cmFileSet const* fileSet, cmLinkItem const& item)
{
return cm::make_unique<TargetPropertyEntryFileSet>(
std::move(dirs), contextSensitiveDirs, std::move(entryCge), fileSet, item);
}
TargetPropertyEntry::TargetPropertyEntry(cmLinkItem const& item)
: LinkItem(item)
{
-7
View File
@@ -10,9 +10,7 @@
class cmLinkItem;
class cmake;
class cmGeneratorTarget;
class cmFileSet;
struct cmGeneratorExpressionDAGChecker;
class cmCompiledGeneratorExpression;
namespace cm {
namespace GenEx {
@@ -32,11 +30,6 @@ public:
cmake& cmakeInstance, const BT<std::string>& propertyValue,
bool evaluateForBuildsystem = false);
static std::unique_ptr<TargetPropertyEntry> CreateFileSet(
std::vector<std::string> dirs, bool contextSensitiveDirs,
std::unique_ptr<cmCompiledGeneratorExpression> entryCge,
cmFileSet const* fileSet, cmLinkItem const& item = NoLinkItem);
virtual std::string const& Evaluate(
cm::GenEx::Context const& context, cmGeneratorTarget const* headTarget,
cmGeneratorExpressionDAGChecker* dagChecker) const = 0;
+27 -23
View File
@@ -12,6 +12,7 @@
#include "cmArgumentParser.h"
#include "cmArgumentParserTypes.h"
#include "cmFileSet.h"
#include "cmFileSetMetadata.h"
#include "cmGeneratorExpression.h"
#include "cmList.h"
#include "cmListFileCache.h"
@@ -232,17 +233,18 @@ bool TargetSourcesImpl::HandleOneFileSet(
return false;
}
if (!args.Type.empty() && !cmFileSet::IsKnownType(args.Type)) {
this->SetError(cmStrCat("File set TYPE may only be \"",
cmFileSet::GetKnownTypes().join("\", \""), '"'));
if (!args.Type.empty() && !cm::FileSetMetadata::IsKnownType(args.Type)) {
this->SetError(
cmStrCat("File set TYPE may only be \"",
cmJoin(cm::FileSetMetadata::GetKnownTypes(), "\", \""), '"'));
return false;
}
if (args.Type.empty() && args.FileSet[0] >= 'A' && args.FileSet[0] <= 'Z' &&
!cmFileSet::IsKnownType(args.FileSet)) {
!cm::FileSetMetadata::IsKnownType(args.FileSet)) {
this->SetError(
cmStrCat("FILE_SET names starting with a capital letter are reserved "
"for built-in file sets and may only be \"",
cmFileSet::GetKnownTypes().join("\", \""), '"'));
cmJoin(cm::FileSetMetadata::GetKnownTypes(), "\", \""), '"'));
return false;
}
if (!args.Type.empty() && args.FileSet[0] >= 'A' && args.FileSet[0] <= 'Z' &&
@@ -254,9 +256,9 @@ bool TargetSourcesImpl::HandleOneFileSet(
}
bool const isDefault = args.Type == args.FileSet ||
(args.Type.empty() && cmFileSet::IsKnownType(args.FileSet));
(args.Type.empty() && cm::FileSetMetadata::IsKnownType(args.FileSet));
if (!isDefault && !cmFileSet::IsValidName(args.FileSet)) {
if (!isDefault && !cm::FileSetMetadata::IsValidName(args.FileSet)) {
this->SetError("Non-default file set name must contain only letters, "
"numbers, and underscores, and must not start with a "
"capital letter or underscore");
@@ -264,8 +266,8 @@ bool TargetSourcesImpl::HandleOneFileSet(
}
std::string type = isDefault ? args.FileSet : args.Type;
cmFileSet::Visibility visibility =
cmFileSet::VisibilityFromName(scope, this->Makefile);
cm::FileSetMetadata::Visibility visibility =
cm::FileSetMetadata::VisibilityFromName(scope, this->Makefile);
auto fileSet =
this->Target->GetOrCreateFileSet(args.FileSet, type, visibility);
@@ -275,12 +277,12 @@ bool TargetSourcesImpl::HandleOneFileSet(
return false;
}
if (cmFileSet::VisibilityIsForSelf(visibility) &&
if (cm::FileSetMetadata::VisibilityIsForSelf(visibility) &&
this->Target->GetType() == cmStateEnums::INTERFACE_LIBRARY &&
!this->Target->IsImported()) {
if (type == cmFileSet::CXX_MODULES) {
if (type == cm::FileSetMetadata::CXX_MODULES) {
this->SetError(
cmStrCat(R"(File set TYPE ")", cmFileSet::CXX_MODULES,
cmStrCat(R"(File set TYPE ")", cm::FileSetMetadata::CXX_MODULES,
R"(" may not have "PUBLIC" )"
R"(or "PRIVATE" visibility on INTERFACE libraries.)"));
return false;
@@ -289,11 +291,12 @@ bool TargetSourcesImpl::HandleOneFileSet(
// FIXME(https://wg21.link/P3470): This condition can go
// away when interface-only module units are a thing.
if (cmFileSet::VisibilityIsForInterface(visibility) &&
!cmFileSet::VisibilityIsForSelf(visibility) &&
if (cm::FileSetMetadata::VisibilityIsForInterface(visibility) &&
!cm::FileSetMetadata::VisibilityIsForSelf(visibility) &&
!this->Target->IsImported()) {
if (type == cmFileSet::CXX_MODULES) {
this->SetError(cmStrCat(R"(File set TYPE ")", cmFileSet::CXX_MODULES,
if (type == cm::FileSetMetadata::CXX_MODULES) {
this->SetError(cmStrCat(R"(File set TYPE ")",
cm::FileSetMetadata::CXX_MODULES,
R"(" may not have "INTERFACE" visibility)"));
return false;
}
@@ -312,10 +315,11 @@ bool TargetSourcesImpl::HandleOneFileSet(
}
if (visibility != fileSet.first->GetVisibility()) {
this->SetError(
cmStrCat("Scope ", scope, " for file set \"", args.FileSet,
"\" does not match original scope ",
cmFileSet::VisibilityToName(fileSet.first->GetVisibility())));
this->SetError(cmStrCat("Scope ", scope, " for file set \"",
args.FileSet,
"\" does not match original scope ",
cm::FileSetMetadata::VisibilityToName(
fileSet.first->GetVisibility())));
return false;
}
}
@@ -332,16 +336,16 @@ bool TargetSourcesImpl::HandleOneFileSet(
if (!baseDirectories.empty()) {
fileSet.first->AddDirectoryEntry(
BT<std::string>(baseDirectories, this->Makefile->GetBacktrace()));
if (type == cmFileSet::HEADERS) {
if (type == cm::FileSetMetadata::HEADERS) {
for (auto const& dir : cmList{ baseDirectories }) {
auto interfaceDirectoriesGenex =
cmStrCat("$<BUILD_INTERFACE:", dir, '>');
if (cmFileSet::VisibilityIsForSelf(visibility)) {
if (cm::FileSetMetadata::VisibilityIsForSelf(visibility)) {
this->Target->AppendProperty("INCLUDE_DIRECTORIES",
interfaceDirectoriesGenex,
this->Makefile->GetBacktrace());
}
if (cmFileSet::VisibilityIsForInterface(visibility)) {
if (cm::FileSetMetadata::VisibilityIsForInterface(visibility)) {
this->Target->AppendProperty("INTERFACE_INCLUDE_DIRECTORIES",
interfaceDirectoriesGenex,
this->Makefile->GetBacktrace());
+8 -7
View File
@@ -27,9 +27,10 @@
#include "cmCryptoHash.h"
#include "cmCustomCommand.h"
#include "cmCustomCommandGenerator.h"
#include "cmFileSet.h"
#include "cmFileSetMetadata.h"
#include "cmGeneratedFileStream.h"
#include "cmGeneratorExpression.h"
#include "cmGeneratorFileSet.h"
#include "cmGeneratorOptions.h"
#include "cmGeneratorTarget.h"
#include "cmGlobalGenerator.h"
@@ -2711,12 +2712,12 @@ void cmVisualStudio10TargetGenerator::WriteAllSources(Elem& e0)
if (si.Kind == cmGeneratorTarget::SourceKindObjectSource ||
si.Kind == cmGeneratorTarget::SourceKindUnityBatched) {
this->OutputSourceSpecificFlags(e2, si.Source);
} else if (fs && fs->GetType() == cmFileSet::CXX_MODULES) {
} else if (fs && fs->GetType() == cm::FileSetMetadata::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 ", cmFileSet::CXX_MODULES,
"\nin a \"FILE_SET TYPE ", cm::FileSetMetadata::CXX_MODULES,
"\" but it is not scheduled for compilation."));
}
if (si.Source->GetPropertyAsBool("SKIP_PRECOMPILE_HEADERS")) {
@@ -2753,12 +2754,12 @@ void cmVisualStudio10TargetGenerator::WriteAllSources(Elem& e0)
}
this->FinishWritingSource(e2, toolSettings);
} else if (fs && fs->GetType() == cmFileSet::CXX_MODULES) {
} else if (fs && fs->GetType() == cm::FileSetMetadata::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 ", cmFileSet::CXX_MODULES,
"\nin a \"FILE_SET TYPE ", cm::FileSetMetadata::CXX_MODULES,
"\" but it is not scheduled for compilation."));
}
}
@@ -2884,9 +2885,9 @@ void cmVisualStudio10TargetGenerator::OutputSourceSpecificFlags(
auto const* fs =
this->GeneratorTarget->GetFileSetForSource(config, source);
char const* compileAsPerConfig = compileAs;
if (fs && fs->GetType() == cmFileSet::CXX_MODULES) {
if (fs && fs->GetType() == cm::FileSetMetadata::CXX_MODULES) {
if (lang == "CXX"_s) {
if (fs->GetType() == cmFileSet::CXX_MODULES) {
if (fs->GetType() == cm::FileSetMetadata::CXX_MODULES) {
isCppModule = true;
if (shouldScanForModules &&
this->GlobalGenerator->IsScanDependenciesSupported()) {
@@ -18,6 +18,7 @@
#include "cmDebuggerVariablesHelper.h"
#include "cmDebuggerVariablesManager.h"
#include "cmFileSet.h"
#include "cmFileSetMetadata.h"
#include "cmGlobalGenerator.h"
#include "cmListFileCache.h"
#include "cmMakefile.h"
@@ -502,7 +503,7 @@ static bool testCreateFromFileSet()
auto dummies = CreateDummies("Foo");
cmFileSet fileSet(dummies.Makefile.get(), "Foo", "HEADERS",
cmFileSet::Visibility::Public);
cm::FileSetMetadata::Visibility::Public);
BT<std::string> directory;
directory.Value = "c:/";
fileSet.AddDirectoryEntry(directory);
@@ -547,7 +548,7 @@ static bool testCreateFromFileSets()
auto dummies = CreateDummies("Foo");
cmFileSet fileSet(dummies.Makefile.get(), "Foo", "HEADERS",
cmFileSet::Visibility::Public);
cm::FileSetMetadata::Visibility::Public);
BT<std::string> directory;
directory.Value = "c:/";
fileSet.AddDirectoryEntry(directory);
+3
View File
@@ -360,6 +360,7 @@ CMAKE_CXX_SOURCES="\
cmFileCopier \
cmFileInstaller \
cmFileSet \
cmFileSetMetadata \
cmFileTime \
cmFileTimeCache \
cmFileTimes \
@@ -385,6 +386,8 @@ CMAKE_CXX_SOURCES="\
cmGeneratorExpressionLexer \
cmGeneratorExpressionNode \
cmGeneratorExpressionParser \
cmGeneratorFileSet \
cmGeneratorFileSets \
cmGeneratorTarget \
cmGeneratorTarget_CompatibleInterface \
cmGeneratorTarget_IncludeDirectories \