cmInstallFileSetGenerator.cxx 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
  2. file LICENSE.rst or https://cmake.org/licensing for details. */
  3. #include "cmInstallFileSetGenerator.h"
  4. #include <algorithm>
  5. #include <map>
  6. #include <string>
  7. #include <utility>
  8. #include <vector>
  9. #include <cm/string_view>
  10. #include <cmext/string_view>
  11. #include "cmFileSet.h"
  12. #include "cmGenExContext.h"
  13. #include "cmGeneratorExpression.h"
  14. #include "cmGeneratorTarget.h"
  15. #include "cmGlobalGenerator.h"
  16. #include "cmInstallType.h"
  17. #include "cmList.h"
  18. #include "cmListFileCache.h"
  19. #include "cmLocalGenerator.h"
  20. #include "cmMessageType.h"
  21. #include "cmStringAlgorithms.h"
  22. #include "cmTarget.h"
  23. cmInstallFileSetGenerator::cmInstallFileSetGenerator(
  24. std::string targetName, std::string fileSetName, cmFileSetDestinations dests,
  25. std::string file_permissions, std::vector<std::string> const& configurations,
  26. std::string const& component, MessageLevel message, bool exclude_from_all,
  27. bool optional, cmListFileBacktrace backtrace)
  28. : cmInstallGenerator("", configurations, component, message,
  29. exclude_from_all, false, std::move(backtrace))
  30. , TargetName(std::move(targetName))
  31. , FileSetName(std::move(fileSetName))
  32. , FilePermissions(std::move(file_permissions))
  33. , FileSetDestinations(std::move(dests))
  34. , Optional(optional)
  35. {
  36. this->ActionsPerConfig = true;
  37. }
  38. cmInstallFileSetGenerator::~cmInstallFileSetGenerator() = default;
  39. bool cmInstallFileSetGenerator::Compute(cmLocalGenerator* lg)
  40. {
  41. this->LocalGenerator = lg;
  42. // Lookup this target in the current directory.
  43. this->Target = lg->FindLocalNonAliasGeneratorTarget(this->TargetName);
  44. if (!this->Target) {
  45. // If no local target has been found, find it in the global scope.
  46. this->Target =
  47. lg->GetGlobalGenerator()->FindGeneratorTarget(this->TargetName);
  48. }
  49. auto const& target = *this->Target->Target;
  50. this->FileSet = target.GetFileSet(this->FileSetName);
  51. if (!this->FileSet) {
  52. // No file set of the given name was ever provided for this target, nothing
  53. // for this generator to do
  54. return true;
  55. }
  56. cmList interfaceFileSetEntries{ target.GetSafeProperty(
  57. cmTarget::GetInterfaceFileSetsPropertyName(this->FileSet->GetType())) };
  58. if (std::find(interfaceFileSetEntries.begin(), interfaceFileSetEntries.end(),
  59. this->FileSetName) != interfaceFileSetEntries.end()) {
  60. if (this->FileSet->GetType() == "HEADERS"_s) {
  61. this->Destination = this->FileSetDestinations.Headers;
  62. } else {
  63. this->Destination = this->FileSetDestinations.CXXModules;
  64. }
  65. } else {
  66. // File set of the given name was provided but it's private, so give up
  67. this->FileSet = nullptr;
  68. return true;
  69. }
  70. if (this->Destination.empty()) {
  71. lg->IssueMessage(MessageType::FATAL_ERROR,
  72. cmStrCat("File set \"", this->FileSetName,
  73. "\" installed by target \"", this->TargetName,
  74. "\" has no destination."));
  75. return false;
  76. }
  77. return true;
  78. }
  79. std::string cmInstallFileSetGenerator::GetDestination(
  80. std::string const& config) const
  81. {
  82. return cmGeneratorExpression::Evaluate(this->Destination,
  83. this->LocalGenerator, config);
  84. }
  85. void cmInstallFileSetGenerator::GenerateScriptForConfig(
  86. std::ostream& os, std::string const& config, Indent indent)
  87. {
  88. if (!this->FileSet) {
  89. return;
  90. }
  91. for (auto const& dirEntry : this->CalculateFilesPerDir(config)) {
  92. std::string destSub;
  93. if (!dirEntry.first.empty()) {
  94. destSub = cmStrCat('/', dirEntry.first);
  95. }
  96. this->AddInstallRule(os, cmStrCat(this->GetDestination(config), destSub),
  97. cmInstallType_FILES, dirEntry.second,
  98. this->GetOptional(), this->FilePermissions.c_str(),
  99. nullptr, nullptr, nullptr, indent);
  100. }
  101. }
  102. std::map<std::string, std::vector<std::string>>
  103. cmInstallFileSetGenerator::CalculateFilesPerDir(
  104. std::string const& config) const
  105. {
  106. std::map<std::string, std::vector<std::string>> result;
  107. cm::GenEx::Context context(this->LocalGenerator, config);
  108. auto dirCges = this->FileSet->CompileDirectoryEntries();
  109. auto dirs =
  110. this->FileSet->EvaluateDirectoryEntries(dirCges, context, this->Target);
  111. auto fileCges = this->FileSet->CompileFileEntries();
  112. for (auto const& fileCge : fileCges) {
  113. this->FileSet->EvaluateFileEntry(dirs, result, fileCge, context,
  114. this->Target);
  115. }
  116. return result;
  117. }