/src/CMake/Source/cmGeneratorExpression.h
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 | | #pragma once |
4 | | |
5 | | #include "cmConfigure.h" // IWYU pragma: keep |
6 | | |
7 | | #include <map> |
8 | | #include <memory> |
9 | | #include <set> |
10 | | #include <string> |
11 | | #include <utility> |
12 | | #include <vector> |
13 | | |
14 | | #include <cm/string_view> |
15 | | |
16 | | #include "cmListFileCache.h" |
17 | | #include "cmLocalGenerator.h" |
18 | | |
19 | | namespace cm { |
20 | | namespace GenEx { |
21 | | struct Context; |
22 | | } |
23 | | } |
24 | | |
25 | | class cmake; |
26 | | class cmCompiledGeneratorExpression; |
27 | | class cmGeneratorTarget; |
28 | | struct cmGeneratorExpressionDAGChecker; |
29 | | struct cmGeneratorExpressionEvaluator; |
30 | | |
31 | | /** \class cmGeneratorExpression |
32 | | * \brief Evaluate generate-time query expression syntax. |
33 | | * |
34 | | * cmGeneratorExpression instances are used by build system generator |
35 | | * implementations to evaluate the $<> generator expression syntax. |
36 | | * Generator expressions are evaluated just before the generate step |
37 | | * writes strings into the build system. They have knowledge of the |
38 | | * build configuration which is not available at configure time. |
39 | | */ |
40 | | class cmGeneratorExpression |
41 | | { |
42 | | public: |
43 | | /** Construct. */ |
44 | | cmGeneratorExpression(cmake& cmakeInstance, |
45 | | cmListFileBacktrace backtrace = cmListFileBacktrace()); |
46 | | ~cmGeneratorExpression(); |
47 | | |
48 | | cmGeneratorExpression(cmGeneratorExpression const&) = delete; |
49 | | cmGeneratorExpression& operator=(cmGeneratorExpression const&) = delete; |
50 | | |
51 | | std::unique_ptr<cmCompiledGeneratorExpression> Parse( |
52 | | std::string input) const; |
53 | | |
54 | | static std::string Evaluate( |
55 | | std::string input, cmLocalGenerator const* lg, std::string const& config, |
56 | | cmGeneratorTarget const* headTarget = nullptr, |
57 | | cmGeneratorExpressionDAGChecker* dagChecker = nullptr, |
58 | | cmGeneratorTarget const* currentTarget = nullptr, |
59 | | std::string const& language = std::string()); |
60 | | |
61 | | static bool ForbidGeneratorExpressions( |
62 | | cmGeneratorTarget const* target, std::string const& propertyName, |
63 | | std::string const& propertyValue, std::string& evaluatedValue, |
64 | | std::map<std::string, std::vector<std::string>>& allowList); |
65 | | |
66 | | static bool ForbidGeneratorExpressions(cmGeneratorTarget const* target, |
67 | | std::string const& propertyName, |
68 | | std::string const& propertyValue); |
69 | | |
70 | | enum PreprocessContext |
71 | | { |
72 | | StripAllGeneratorExpressions, |
73 | | BuildInterface, |
74 | | InstallInterface |
75 | | }; |
76 | | |
77 | | static std::string Preprocess(cm::string_view input, |
78 | | PreprocessContext context, |
79 | | cm::string_view importPrefix = {}); |
80 | | |
81 | | static std::string Collect( |
82 | | std::string const& input, |
83 | | std::map<std::string, std::vector<std::string>>& collected); |
84 | | |
85 | | static void Split(std::string const& input, |
86 | | std::vector<std::string>& output); |
87 | | |
88 | | static cm::string_view::size_type Find(cm::string_view input); |
89 | | |
90 | | static bool IsValidTargetName(std::string const& input); |
91 | | |
92 | | static std::string StripEmptyListElements(std::string const& input); |
93 | | |
94 | | static bool StartsWithGeneratorExpression(std::string const& input) |
95 | 2.35k | { |
96 | 2.35k | return input.length() >= 2 && input[0] == '$' && input[1] == '<'; |
97 | 2.35k | } |
98 | | static bool StartsWithGeneratorExpression(char const* input) |
99 | 3.33M | { |
100 | 3.33M | return input && input[0] == '$' && input[1] == '<'; |
101 | 3.33M | } |
102 | | |
103 | | static void ReplaceInstallPrefix(std::string& input, |
104 | | std::string const& replacement); |
105 | | |
106 | | private: |
107 | | cmake& CMakeInstance; |
108 | | cmListFileBacktrace Backtrace; |
109 | | }; |
110 | | |
111 | | class cmCompiledGeneratorExpression |
112 | | { |
113 | | public: |
114 | | ~cmCompiledGeneratorExpression(); |
115 | | |
116 | | cmCompiledGeneratorExpression(cmCompiledGeneratorExpression const&) = delete; |
117 | | cmCompiledGeneratorExpression& operator=( |
118 | | cmCompiledGeneratorExpression const&) = delete; |
119 | | |
120 | | std::string const& Evaluate( |
121 | | cmLocalGenerator const* lg, std::string const& config, |
122 | | cmGeneratorTarget const* headTarget = nullptr) const; |
123 | | |
124 | | std::string const& Evaluate( |
125 | | cm::GenEx::Context const& context, |
126 | | cmGeneratorExpressionDAGChecker* dagChecker, |
127 | | cmGeneratorTarget const* headTarget = nullptr, |
128 | | cmGeneratorTarget const* currentTarget = nullptr) const; |
129 | | |
130 | | /** Get set of targets found during evaluations. */ |
131 | | std::set<cmGeneratorTarget*> const& GetTargets() const |
132 | 0 | { |
133 | 0 | return this->DependTargets; |
134 | 0 | } |
135 | | |
136 | | std::set<std::string> const& GetSeenTargetProperties() const |
137 | 0 | { |
138 | 0 | return this->SeenTargetProperties; |
139 | 0 | } |
140 | | |
141 | | std::set<cmGeneratorTarget const*> const& GetAllTargetsSeen() const |
142 | 0 | { |
143 | 0 | return this->AllTargetsSeen; |
144 | 0 | } |
145 | | |
146 | 0 | std::string const& GetInput() const { return this->Input; } |
147 | | |
148 | 0 | cmListFileBacktrace GetBacktrace() const { return this->Backtrace; } |
149 | | bool GetHadContextSensitiveCondition() const |
150 | 0 | { |
151 | 0 | return this->HadContextSensitiveCondition; |
152 | 0 | } |
153 | | bool GetHadHeadSensitiveCondition() const |
154 | 0 | { |
155 | 0 | return this->HadHeadSensitiveCondition; |
156 | 0 | } |
157 | | bool GetHadLinkLanguageSensitiveCondition() const |
158 | 0 | { |
159 | 0 | return this->HadLinkLanguageSensitiveCondition; |
160 | 0 | } |
161 | | std::set<cmGeneratorTarget const*> GetSourceSensitiveTargets() const |
162 | 0 | { |
163 | 0 | return this->SourceSensitiveTargets; |
164 | 0 | } |
165 | | |
166 | | void SetEvaluateForBuildsystem(bool eval) |
167 | 0 | { |
168 | 0 | this->EvaluateForBuildsystem = eval; |
169 | 0 | } |
170 | | |
171 | 0 | void SetQuiet(bool quiet) { this->Quiet = quiet; } |
172 | | |
173 | | void GetMaxLanguageStandard(cmGeneratorTarget const* tgt, |
174 | | std::map<std::string, std::string>& mapping); |
175 | | |
176 | | private: |
177 | | cmCompiledGeneratorExpression(cmake& cmakeInstance, |
178 | | cmListFileBacktrace backtrace, |
179 | | std::string input); |
180 | | |
181 | | friend class cmGeneratorExpression; |
182 | | |
183 | | cmListFileBacktrace Backtrace; |
184 | | std::vector<std::unique_ptr<cmGeneratorExpressionEvaluator>> Evaluators; |
185 | | std::string const Input; |
186 | | bool NeedsEvaluation; |
187 | | bool EvaluateForBuildsystem = false; |
188 | | bool Quiet = false; |
189 | | |
190 | | mutable std::set<cmGeneratorTarget*> DependTargets; |
191 | | mutable std::set<cmGeneratorTarget const*> AllTargetsSeen; |
192 | | mutable std::set<std::string> SeenTargetProperties; |
193 | | mutable std::map<cmGeneratorTarget const*, |
194 | | std::map<std::string, std::string>> |
195 | | MaxLanguageStandard; |
196 | | mutable std::string Output; |
197 | | mutable bool HadContextSensitiveCondition = false; |
198 | | mutable bool HadHeadSensitiveCondition = false; |
199 | | mutable bool HadLinkLanguageSensitiveCondition = false; |
200 | | mutable std::set<cmGeneratorTarget const*> SourceSensitiveTargets; |
201 | | }; |
202 | | |
203 | | class cmGeneratorExpressionInterpreter |
204 | | { |
205 | | public: |
206 | | cmGeneratorExpressionInterpreter(cmLocalGenerator const* localGenerator, |
207 | | std::string config, |
208 | | cmGeneratorTarget const* headTarget, |
209 | | std::string language = std::string()) |
210 | 0 | : GeneratorExpression(*localGenerator->GetCMakeInstance()) |
211 | 0 | , LocalGenerator(localGenerator) |
212 | 0 | , Config(std::move(config)) |
213 | 0 | , HeadTarget(headTarget) |
214 | 0 | , Language(std::move(language)) |
215 | 0 | { |
216 | 0 | } |
217 | | |
218 | | cmGeneratorExpressionInterpreter(cmGeneratorExpressionInterpreter const&) = |
219 | | delete; |
220 | | cmGeneratorExpressionInterpreter& operator=( |
221 | | cmGeneratorExpressionInterpreter const&) = delete; |
222 | | |
223 | | std::string const& Evaluate(std::string expression, |
224 | | std::string const& property); |
225 | | |
226 | | protected: |
227 | | cmGeneratorExpression GeneratorExpression; |
228 | | std::unique_ptr<cmCompiledGeneratorExpression> CompiledGeneratorExpression; |
229 | | cmLocalGenerator const* LocalGenerator = nullptr; |
230 | | std::string Config; |
231 | | cmGeneratorTarget const* HeadTarget = nullptr; |
232 | | std::string Language; |
233 | | }; |