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