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