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