1
0

cmFileSet.cxx 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
  2. file Copyright.txt or https://cmake.org/licensing for details. */
  3. #include "cmFileSet.h"
  4. #include <sstream>
  5. #include <string>
  6. #include <utility>
  7. #include <vector>
  8. #include "cmsys/RegularExpression.hxx"
  9. #include "cmGeneratorExpression.h"
  10. #include "cmListFileCache.h"
  11. #include "cmLocalGenerator.h"
  12. #include "cmMessageType.h"
  13. #include "cmStringAlgorithms.h"
  14. #include "cmSystemTools.h"
  15. #include "cmake.h"
  16. cmFileSet::cmFileSet(std::string name, std::string type)
  17. : Name(std::move(name))
  18. , Type(std::move(type))
  19. {
  20. }
  21. void cmFileSet::ClearDirectoryEntries()
  22. {
  23. this->DirectoryEntries.clear();
  24. }
  25. void cmFileSet::AddDirectoryEntry(BT<std::string> directories)
  26. {
  27. this->DirectoryEntries.push_back(std::move(directories));
  28. }
  29. void cmFileSet::ClearFileEntries()
  30. {
  31. this->FileEntries.clear();
  32. }
  33. void cmFileSet::AddFileEntry(BT<std::string> files)
  34. {
  35. this->FileEntries.push_back(std::move(files));
  36. }
  37. std::vector<std::unique_ptr<cmCompiledGeneratorExpression>>
  38. cmFileSet::CompileFileEntries() const
  39. {
  40. std::vector<std::unique_ptr<cmCompiledGeneratorExpression>> result;
  41. for (auto const& entry : this->FileEntries) {
  42. for (auto const& ex : cmExpandedList(entry.Value)) {
  43. cmGeneratorExpression ge(entry.Backtrace);
  44. auto cge = ge.Parse(ex);
  45. result.push_back(std::move(cge));
  46. }
  47. }
  48. return result;
  49. }
  50. std::vector<std::unique_ptr<cmCompiledGeneratorExpression>>
  51. cmFileSet::CompileDirectoryEntries() const
  52. {
  53. std::vector<std::unique_ptr<cmCompiledGeneratorExpression>> result;
  54. for (auto const& entry : this->DirectoryEntries) {
  55. for (auto const& ex : cmExpandedList(entry.Value)) {
  56. cmGeneratorExpression ge(entry.Backtrace);
  57. auto cge = ge.Parse(ex);
  58. result.push_back(std::move(cge));
  59. }
  60. }
  61. return result;
  62. }
  63. std::vector<std::string> cmFileSet::EvaluateDirectoryEntries(
  64. const std::vector<std::unique_ptr<cmCompiledGeneratorExpression>>& cges,
  65. cmLocalGenerator* lg, const std::string& config,
  66. const cmGeneratorTarget* target,
  67. cmGeneratorExpressionDAGChecker* dagChecker) const
  68. {
  69. std::vector<std::string> result;
  70. for (auto const& cge : cges) {
  71. auto entry = cge->Evaluate(lg, config, target, dagChecker);
  72. auto dirs = cmExpandedList(entry);
  73. for (std::string dir : dirs) {
  74. if (!cmSystemTools::FileIsFullPath(dir)) {
  75. dir = cmStrCat(lg->GetCurrentSourceDirectory(), '/', dir);
  76. }
  77. auto collapsedDir = cmSystemTools::CollapseFullPath(dir);
  78. for (auto const& priorDir : result) {
  79. auto collapsedPriorDir = cmSystemTools::CollapseFullPath(priorDir);
  80. if (!cmSystemTools::SameFile(collapsedDir, collapsedPriorDir) &&
  81. (cmSystemTools::IsSubDirectory(collapsedDir, collapsedPriorDir) ||
  82. cmSystemTools::IsSubDirectory(collapsedPriorDir, collapsedDir))) {
  83. lg->GetCMakeInstance()->IssueMessage(
  84. MessageType::FATAL_ERROR,
  85. cmStrCat(
  86. "Base directories in file set cannot be subdirectories of each "
  87. "other:\n ",
  88. priorDir, "\n ", dir),
  89. cge->GetBacktrace());
  90. return {};
  91. }
  92. }
  93. result.push_back(dir);
  94. }
  95. }
  96. return result;
  97. }
  98. void cmFileSet::EvaluateFileEntry(
  99. const std::vector<std::string>& dirs,
  100. std::map<std::string, std::vector<std::string>>& filesPerDir,
  101. const std::unique_ptr<cmCompiledGeneratorExpression>& cge,
  102. cmLocalGenerator* lg, const std::string& config,
  103. const cmGeneratorTarget* target,
  104. cmGeneratorExpressionDAGChecker* dagChecker) const
  105. {
  106. auto files = cge->Evaluate(lg, config, target, dagChecker);
  107. for (std::string file : cmExpandedList(files)) {
  108. if (!cmSystemTools::FileIsFullPath(file)) {
  109. file = cmStrCat(lg->GetCurrentSourceDirectory(), '/', file);
  110. }
  111. auto collapsedFile = cmSystemTools::CollapseFullPath(file);
  112. bool found = false;
  113. std::string relDir;
  114. for (auto const& dir : dirs) {
  115. auto collapsedDir = cmSystemTools::CollapseFullPath(dir);
  116. if (cmSystemTools::IsSubDirectory(collapsedFile, collapsedDir)) {
  117. found = true;
  118. relDir = cmSystemTools::GetParentDirectory(
  119. cmSystemTools::RelativePath(collapsedDir, collapsedFile));
  120. break;
  121. }
  122. }
  123. if (!found) {
  124. std::ostringstream e;
  125. e << "File:\n " << file
  126. << "\nmust be in one of the file set's base directories:";
  127. for (auto const& dir : dirs) {
  128. e << "\n " << dir;
  129. }
  130. lg->GetCMakeInstance()->IssueMessage(MessageType::FATAL_ERROR, e.str(),
  131. cge->GetBacktrace());
  132. return;
  133. }
  134. filesPerDir[relDir].push_back(file);
  135. }
  136. }
  137. bool cmFileSet::IsValidName(const std::string& name)
  138. {
  139. static const cmsys::RegularExpression regex("^[a-z0-9][a-zA-Z0-9_]*$");
  140. cmsys::RegularExpressionMatch match;
  141. return regex.find(name.c_str(), match);
  142. }