cmGeneratorExpression.h 6.37 KB
Newer Older
1 2
/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
   file Copyright.txt or https://cmake.org/licensing for details.  */
3 4 5
#ifndef cmGeneratorExpression_h
#define cmGeneratorExpression_h

6
#include "cmConfigure.h" // IWYU pragma: keep
7

8
#include "cmListFileCache.h"
9

10
#include <map>
11
#include <memory>
12 13
#include <set>
#include <string>
wahikihiki's avatar
wahikihiki committed
14
#include <utility>
15
#include <vector>
16

17
class cmCompiledGeneratorExpression;
18
class cmGeneratorTarget;
19
class cmLocalGenerator;
20
struct cmGeneratorExpressionContext;
21
struct cmGeneratorExpressionDAGChecker;
22
struct cmGeneratorExpressionEvaluator;
23

24 25 26 27 28 29 30 31 32 33 34 35
/** \class cmGeneratorExpression
 * \brief Evaluate generate-time query expression syntax.
 *
 * cmGeneratorExpression instances are used by build system generator
 * implementations to evaluate the $<> generator expression syntax.
 * Generator expressions are evaluated just before the generate step
 * writes strings into the build system.  They have knowledge of the
 * build configuration which is not available at configure time.
 */
class cmGeneratorExpression
{
public:
36
  /** Construct. */
wahikihiki's avatar
wahikihiki committed
37
  cmGeneratorExpression(cmListFileBacktrace backtrace = cmListFileBacktrace());
38 39
  ~cmGeneratorExpression();

wahikihiki's avatar
wahikihiki committed
40 41 42
  cmGeneratorExpression(cmGeneratorExpression const&) = delete;
  cmGeneratorExpression& operator=(cmGeneratorExpression const&) = delete;

43 44 45
  std::unique_ptr<cmCompiledGeneratorExpression> Parse(
    std::string const& input);
  std::unique_ptr<cmCompiledGeneratorExpression> Parse(const char* input);
46

47 48
  enum PreprocessContext
  {
49 50 51
    StripAllGeneratorExpressions,
    BuildInterface,
    InstallInterface
52 53
  };

54
  static std::string Preprocess(const std::string& input,
55 56
                                PreprocessContext context,
                                bool resolveRelative = false);
57

58 59 60 61
  static void Split(const std::string& input,
                    std::vector<std::string>& output);

  static std::string::size_type Find(const std::string& input);
62

63
  static bool IsValidTargetName(const std::string& input);
64

65
  static std::string StripEmptyListElements(const std::string& input);
66

67 68 69 70 71 72 73 74 75
  static inline bool StartsWithGeneratorExpression(const std::string& input)
  {
    return input.length() >= 2 && input[0] == '$' && input[1] == '<';
  }
  static inline bool StartsWithGeneratorExpression(const char* input)
  {
    return input != nullptr && input[0] == '$' && input[1] == '<';
  }

76
private:
77
  cmListFileBacktrace Backtrace;
78
};
79

80 81 82
class cmCompiledGeneratorExpression
{
public:
wahikihiki's avatar
wahikihiki committed
83 84 85 86 87 88
  ~cmCompiledGeneratorExpression();

  cmCompiledGeneratorExpression(cmCompiledGeneratorExpression const&) = delete;
  cmCompiledGeneratorExpression& operator=(
    cmCompiledGeneratorExpression const&) = delete;

89 90 91 92 93 94 95 96 97 98 99
  const std::string& Evaluate(
    cmLocalGenerator* lg, const std::string& config, bool quiet = false,
    cmGeneratorTarget const* headTarget = nullptr,
    cmGeneratorTarget const* currentTarget = nullptr,
    cmGeneratorExpressionDAGChecker* dagChecker = nullptr,
    std::string const& language = std::string()) const;
  const std::string& Evaluate(
    cmLocalGenerator* lg, const std::string& config, bool quiet,
    cmGeneratorTarget const* headTarget,
    cmGeneratorExpressionDAGChecker* dagChecker,
    std::string const& language = std::string()) const;
100

101
  /** Get set of targets found during evaluations.  */
102
  std::set<cmGeneratorTarget*> const& GetTargets() const
103 104 105
  {
    return this->DependTargets;
  }
106

107
  std::set<std::string> const& GetSeenTargetProperties() const
108 109 110
  {
    return this->SeenTargetProperties;
  }
111

112
  std::set<cmGeneratorTarget const*> const& GetAllTargetsSeen() const
113 114 115
  {
    return this->AllTargetsSeen;
  }
116

117
  std::string const& GetInput() const { return this->Input; }
118

119
  cmListFileBacktrace GetBacktrace() const { return this->Backtrace; }
120 121 122 123
  bool GetHadContextSensitiveCondition() const
  {
    return this->HadContextSensitiveCondition;
  }
124 125 126 127
  bool GetHadHeadSensitiveCondition() const
  {
    return this->HadHeadSensitiveCondition;
  }
128
  std::set<cmGeneratorTarget const*> GetSourceSensitiveTargets() const
129 130 131
  {
    return this->SourceSensitiveTargets;
  }
132

133 134 135 136 137
  void SetEvaluateForBuildsystem(bool eval)
  {
    this->EvaluateForBuildsystem = eval;
  }

138
  void GetMaxLanguageStandard(cmGeneratorTarget const* tgt,
139
                              std::map<std::string, std::string>& mapping);
140

141
private:
142
  const std::string& EvaluateWithContext(
143 144
    cmGeneratorExpressionContext& context,
    cmGeneratorExpressionDAGChecker* dagChecker) const;
145

wahikihiki's avatar
wahikihiki committed
146 147
  cmCompiledGeneratorExpression(cmListFileBacktrace backtrace,
                                std::string input);
148

149 150
  friend class cmGeneratorExpression;

151 152 153
  cmListFileBacktrace Backtrace;
  std::vector<cmGeneratorExpressionEvaluator*> Evaluators;
  const std::string Input;
154
  bool NeedsEvaluation;
155

156 157
  mutable std::set<cmGeneratorTarget*> DependTargets;
  mutable std::set<cmGeneratorTarget const*> AllTargetsSeen;
158
  mutable std::set<std::string> SeenTargetProperties;
159
  mutable std::map<cmGeneratorTarget const*,
160
                   std::map<std::string, std::string>>
161
    MaxLanguageStandard;
162
  mutable std::string Output;
163
  mutable bool HadContextSensitiveCondition;
164
  mutable bool HadHeadSensitiveCondition;
165
  mutable std::set<cmGeneratorTarget const*> SourceSensitiveTargets;
166
  bool EvaluateForBuildsystem;
167
};
168

169 170 171 172
class cmGeneratorExpressionInterpreter
{
public:
  cmGeneratorExpressionInterpreter(cmLocalGenerator* localGenerator,
wahikihiki's avatar
wahikihiki committed
173
                                   std::string config,
174
                                   cmGeneratorTarget const* headTarget,
wahikihiki's avatar
wahikihiki committed
175
                                   std::string lang = std::string())
176
    : LocalGenerator(localGenerator)
wahikihiki's avatar
wahikihiki committed
177
    , Config(std::move(config))
178
    , HeadTarget(headTarget)
wahikihiki's avatar
wahikihiki committed
179
    , Language(std::move(lang))
180 181
  {
  }
182

wahikihiki's avatar
wahikihiki committed
183 184 185 186 187
  cmGeneratorExpressionInterpreter(cmGeneratorExpressionInterpreter const&) =
    delete;
  cmGeneratorExpressionInterpreter& operator=(
    cmGeneratorExpressionInterpreter const&) = delete;

188 189 190 191
  const std::string& Evaluate(const char* expression,
                              const std::string& property);
  const std::string& Evaluate(const std::string& expression,
                              const std::string& property)
192 193 194
  {
    return this->Evaluate(expression.c_str(), property);
  }
195 196 197 198 199 200

protected:
  cmGeneratorExpression GeneratorExpression;
  std::unique_ptr<cmCompiledGeneratorExpression> CompiledGeneratorExpression;
  cmLocalGenerator* LocalGenerator = nullptr;
  std::string Config;
201
  cmGeneratorTarget const* HeadTarget = nullptr;
202
  std::string Language;
203 204
};

205
#endif