/* 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); } }