mirror of
https://gitlab.kitware.com/cmake/cmake.git
synced 2026-09-25 04:09:36 +03:00
cmGeneratorFileSet: Support different mappings
The full path of a file in a file set can be broken into groups like `<base>/[<sub>/]<name>`, where `<base>` is the base directory and `<name>` is the file name without any directory components. Existing users evaluate file set files as a mapping from `<rel>` to the full path. However, CPS export needs files grouped by base directory, and cares about the composition of `<rel>` and `<name>`. To facilitate obtaining this information in a more useful form, refactor how we extract file set files to allow the user to pass a lambda 'handler' for each file, which has the base directory, full path, and path relative to the base directory available. (We already obtained `<rel>` from the latter, so while this technically means the existing use needs to do additional work, in practice it just means the call to get `<rel>` moves to the lambda.) Because there are many existing users that would need to duplicate the lambda, the old methods are retained as-is, although this does result in minor code duplication between `GetFiles` (which calls the overload of `EvaluateFileEntry` which fills the old file map) and `EvaluateFiles` (which is essentially `GetFiles`, but accepts a user-provided 'handler' lambda rather than directly producing a file map).
This commit is contained in:
@@ -498,8 +498,7 @@ std::vector<std::string> cmGeneratorFileSet::EvaluateDirectoryEntries(
|
||||
}
|
||||
|
||||
void cmGeneratorFileSet::EvaluateFileEntry(
|
||||
std::vector<std::string> const& dirs,
|
||||
std::map<std::string, std::vector<std::string>>& filesPerDir,
|
||||
std::vector<std::string> const& dirs, EvaluateFileEntryFunction handler,
|
||||
std::unique_ptr<cmCompiledGeneratorExpression> const& cge,
|
||||
cm::GenEx::Context const& context, cmGeneratorTarget const* target,
|
||||
cmGeneratorExpressionDAGChecker* dagChecker) const
|
||||
@@ -510,18 +509,17 @@ void cmGeneratorFileSet::EvaluateFileEntry(
|
||||
file = cmStrCat(context.LG->GetCurrentSourceDirectory(), '/', file);
|
||||
}
|
||||
auto collapsedFile = cmSystemTools::CollapseFullPath(file);
|
||||
bool found = false;
|
||||
std::string relDir;
|
||||
std::string baseDir;
|
||||
std::string relPath;
|
||||
for (auto const& dir : dirs) {
|
||||
auto collapsedDir = cmSystemTools::CollapseFullPath(dir);
|
||||
if (cmSystemTools::IsSubDirectory(collapsedFile, collapsedDir)) {
|
||||
found = true;
|
||||
relDir = cmSystemTools::GetParentDirectory(
|
||||
cmSystemTools::RelativePath(collapsedDir, collapsedFile));
|
||||
baseDir = collapsedDir;
|
||||
relPath = cmSystemTools::RelativePath(collapsedDir, collapsedFile);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
if (baseDir.empty()) {
|
||||
std::ostringstream e;
|
||||
e << "File:\n " << file
|
||||
<< "\nmust be in one of the file set's base directories:";
|
||||
@@ -533,10 +531,24 @@ void cmGeneratorFileSet::EvaluateFileEntry(
|
||||
return;
|
||||
}
|
||||
|
||||
filesPerDir[relDir].push_back(file);
|
||||
handler(std::move(baseDir), std::move(relPath), std::move(file));
|
||||
}
|
||||
}
|
||||
|
||||
void cmGeneratorFileSet::EvaluateFileEntry(
|
||||
std::vector<std::string> const& dirs, FileMap& filesPerDir,
|
||||
std::unique_ptr<cmCompiledGeneratorExpression> const& cge,
|
||||
cm::GenEx::Context const& context, cmGeneratorTarget const* target,
|
||||
cmGeneratorExpressionDAGChecker* dagChecker) const
|
||||
{
|
||||
auto handler = [&filesPerDir](std::string&& /*baseDir*/,
|
||||
std::string&& relPath, std::string&& file) {
|
||||
std::string relDir = cmSystemTools::GetParentDirectory(relPath);
|
||||
filesPerDir[std::move(relDir)].emplace_back(std::move(file));
|
||||
};
|
||||
this->EvaluateFileEntry(dirs, handler, cge, context, target, dagChecker);
|
||||
}
|
||||
|
||||
namespace {
|
||||
bool EntryIsContextSensitive(
|
||||
std::unique_ptr<cmCompiledGeneratorExpression> const& cge)
|
||||
@@ -577,10 +589,9 @@ std::pair<std::vector<std::string>, bool> cmGeneratorFileSet::GetDirectories(
|
||||
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
|
||||
std::pair<cmGeneratorFileSet::FileMap, bool> cmGeneratorFileSet::GetFiles(
|
||||
cm::GenEx::Context const& context, cmGeneratorTarget const* target,
|
||||
cmGeneratorExpressionDAGChecker* dagChecker) const
|
||||
{
|
||||
auto directories = this->GetDirectories(context, target, dagChecker);
|
||||
|
||||
@@ -596,3 +607,20 @@ cmGeneratorFileSet::GetFiles(cm::GenEx::Context const& context,
|
||||
|
||||
return std::make_pair(std::move(files), contextSensitive);
|
||||
}
|
||||
|
||||
bool cmGeneratorFileSet::EvaluateFiles(
|
||||
cm::GenEx::Context const& context, cmGeneratorTarget const* target,
|
||||
EvaluateFileEntryFunction callback,
|
||||
cmGeneratorExpressionDAGChecker* dagChecker) const
|
||||
{
|
||||
auto directories = this->GetDirectories(context, target, dagChecker);
|
||||
|
||||
auto const& fileEntries = this->CompileFileEntries();
|
||||
for (auto const& entry : fileEntries) {
|
||||
this->EvaluateFileEntry(directories.first, callback, entry, context,
|
||||
target, dagChecker);
|
||||
}
|
||||
return directories.second ||
|
||||
std::any_of(fileEntries.begin(), fileEntries.end(),
|
||||
EntryIsContextSensitive);
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
#include "cmConfigure.h" // IWYU pragma: keep
|
||||
|
||||
#include <functional>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
@@ -79,6 +80,8 @@ public:
|
||||
cm::GenEx::Context const& context, cmGeneratorTarget const* target,
|
||||
cmGeneratorExpressionDAGChecker* dagChecker = nullptr) const;
|
||||
|
||||
using FileMap = std::map<std::string, std::vector<std::string>>;
|
||||
|
||||
// returned value:
|
||||
// first: list of directories
|
||||
// second: is context sensitive
|
||||
@@ -88,7 +91,7 @@ public:
|
||||
// returned value:
|
||||
// first: list of files per directory
|
||||
// second: is context sensitive
|
||||
std::pair<std::map<std::string, std::vector<std::string>>, bool> GetFiles(
|
||||
std::pair<FileMap, bool> GetFiles(
|
||||
cm::GenEx::Context const& context, cmGeneratorTarget const* target,
|
||||
cmGeneratorExpressionDAGChecker* dagChecker = nullptr) const;
|
||||
|
||||
@@ -103,9 +106,23 @@ public:
|
||||
cm::GenEx::Context const& context, cmGeneratorTarget const* target,
|
||||
cmGeneratorExpressionDAGChecker* dagChecker = nullptr) const;
|
||||
|
||||
using EvaluateFileEntryFunction =
|
||||
std::function<void(std::string&&, std::string&&, std::string&&)>;
|
||||
|
||||
// returned value: is context sensitive
|
||||
bool EvaluateFiles(
|
||||
cm::GenEx::Context const& context, cmGeneratorTarget const* target,
|
||||
EvaluateFileEntryFunction callback,
|
||||
cmGeneratorExpressionDAGChecker* dagChecker = nullptr) const;
|
||||
|
||||
void EvaluateFileEntry(
|
||||
std::vector<std::string> const& dirs,
|
||||
std::map<std::string, std::vector<std::string>>& filesPerDir,
|
||||
std::vector<std::string> const& dirs, EvaluateFileEntryFunction handler,
|
||||
std::unique_ptr<cmCompiledGeneratorExpression> const& cge,
|
||||
cm::GenEx::Context const& context, cmGeneratorTarget const* target,
|
||||
cmGeneratorExpressionDAGChecker* dagChecker = nullptr) const;
|
||||
|
||||
void EvaluateFileEntry(
|
||||
std::vector<std::string> const& dirs, FileMap& filesPerDir,
|
||||
std::unique_ptr<cmCompiledGeneratorExpression> const& cge,
|
||||
cm::GenEx::Context const& context, cmGeneratorTarget const* target,
|
||||
cmGeneratorExpressionDAGChecker* dagChecker = nullptr) const;
|
||||
|
||||
Reference in New Issue
Block a user