From f2a44a8afabe6d0d87f1b5d4acf31b2049a021fd Mon Sep 17 00:00:00 2001 From: Kyle Edwards Date: Wed, 16 Jun 2021 17:09:59 -0400 Subject: cmTarget: Add cmFileSet and associated properties --- Source/cmFileSet.cxx | 151 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 151 insertions(+) create mode 100644 Source/cmFileSet.cxx (limited to 'Source/cmFileSet.cxx') diff --git a/Source/cmFileSet.cxx b/Source/cmFileSet.cxx new file mode 100644 index 0000000000..08d56ba1aa --- /dev/null +++ b/Source/cmFileSet.cxx @@ -0,0 +1,151 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ +#include "cmFileSet.h" + +#include +#include +#include +#include + +#include "cmGeneratorExpression.h" +#include "cmListFileCache.h" +#include "cmLocalGenerator.h" +#include "cmMessageType.h" +#include "cmStringAlgorithms.h" +#include "cmSystemTools.h" +#include "cmake.h" + +cmFileSet::cmFileSet(std::string name, std::string type) + : Name(std::move(name)) + , Type(std::move(type)) +{ +} + +void cmFileSet::ClearDirectoryEntries() +{ + this->DirectoryEntries.clear(); +} + +void cmFileSet::AddDirectoryEntry(BT directories) +{ + this->DirectoryEntries.push_back(std::move(directories)); +} + +void cmFileSet::ClearFileEntries() +{ + this->FileEntries.clear(); +} + +void cmFileSet::AddFileEntry(BT files) +{ + this->FileEntries.push_back(std::move(files)); +} + +std::vector> +cmFileSet::CompileFileEntries() const +{ + std::vector> result; + + for (auto const& entry : this->FileEntries) { + for (auto const& ex : cmExpandedList(entry.Value)) { + cmGeneratorExpression ge(entry.Backtrace); + auto cge = ge.Parse(ex); + result.push_back(std::move(cge)); + } + } + + return result; +} + +std::vector> +cmFileSet::CompileDirectoryEntries() const +{ + std::vector> result; + + for (auto const& entry : this->DirectoryEntries) { + for (auto const& ex : cmExpandedList(entry.Value)) { + cmGeneratorExpression ge(entry.Backtrace); + auto cge = ge.Parse(ex); + result.push_back(std::move(cge)); + } + } + + return result; +} + +std::vector cmFileSet::EvaluateDirectoryEntries( + const std::vector>& cges, + cmLocalGenerator* lg, const std::string& config, + const cmGeneratorTarget* target, + cmGeneratorExpressionDAGChecker* dagChecker) const +{ + std::vector result; + for (auto const& cge : cges) { + auto entry = cge->Evaluate(lg, config, target, dagChecker); + auto dirs = cmExpandedList(entry); + for (std::string dir : dirs) { + if (!cmSystemTools::FileIsFullPath(dir)) { + dir = cmStrCat(lg->GetCurrentSourceDirectory(), '/', dir); + } + auto collapsedDir = cmSystemTools::CollapseFullPath(dir); + for (auto const& priorDir : result) { + auto collapsedPriorDir = cmSystemTools::CollapseFullPath(priorDir); + if (!cmSystemTools::SameFile(collapsedDir, collapsedPriorDir) && + (cmSystemTools::IsSubDirectory(collapsedDir, collapsedPriorDir) || + cmSystemTools::IsSubDirectory(collapsedPriorDir, collapsedDir))) { + 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( + const std::vector& dirs, + std::map>& filesPerDir, + const std::unique_ptr& cge, + cmLocalGenerator* lg, const std::string& config, + const cmGeneratorTarget* target, + cmGeneratorExpressionDAGChecker* dagChecker) const +{ + auto files = cge->Evaluate(lg, config, target, dagChecker); + for (std::string file : cmExpandedList(files)) { + if (!cmSystemTools::FileIsFullPath(file)) { + file = cmStrCat(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; + } + lg->GetCMakeInstance()->IssueMessage(MessageType::FATAL_ERROR, e.str(), + cge->GetBacktrace()); + return; + } + + filesPerDir[relDir].push_back(file); + } +} -- cgit v1.2.1