Coverage Report

Created: 2026-10-28 06:38

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/CMake/Source/cmRule.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 <cstddef>
8
#include <string>
9
#include <type_traits>
10
#include <unordered_map>
11
#include <utility>
12
#include <vector>
13
14
#include "cmAlgorithms.h"
15
#include "cmListFileCache.h"
16
#include "cmPropertyMap.h"
17
#include "cmValue.h"
18
19
class cmMakefile;
20
class cmTarget;
21
class cmFileSet;
22
class cmSourceFile;
23
24
namespace cm {
25
26
enum class RuleScope
27
{
28
  Local,
29
  Global
30
};
31
32
template <typename E>
33
struct enum_hash
34
{
35
  typename std::enable_if<std::is_enum<E>::value, std::size_t>::type
36
  operator()(E const key) const
37
0
  {
38
0
    return static_cast<std::size_t>(key);
39
0
  }
40
};
41
}
42
43
//
44
// cmRule: base class for various rule types
45
//
46
class cmRule
47
{
48
public:
49
  using CustomCommand = std::vector<std::string>;
50
  using CustomCommands = std::vector<CustomCommand>;
51
52
0
  virtual ~cmRule() = default;
53
54
  cmRule& operator=(cmRule const&) = delete;
55
56
0
  cmMakefile& GetMakefile() const { return *this->Makefile; }
57
58
  /** Get the name of the rule */
59
0
  std::string const& GetName() const { return this->Name; }
60
  virtual std::string const& GetParentName() const;
61
62
  /** Get the command lines.  */
63
  virtual CustomCommands const& GetCommands() const = 0;
64
  /** Get the output files.  */
65
  virtual std::vector<std::string> const& GetOutputs() const = 0;
66
67
  /** Get the extra files produced by the command.  */
68
  virtual std::vector<std::string> const& GetByproducts() const = 0;
69
70
  /** Get the vector that holds the list of dependencies. */
71
  virtual std::vector<std::string> const& GetDepends() const = 0;
72
  /** Get the file that holds the list of dependencies. */
73
  virtual std::string const& GetDepfile() const = 0;
74
75
  enum class ConfiguratorType
76
  {
77
    FileSet,
78
    Source
79
  };
80
  enum class ChainConfigurators
81
  {
82
    No,
83
    Yes
84
  };
85
  using ConfiguratorSet =
86
    std::vector<std::pair<std::string const*, std::string const*>>;
87
  void SetConfigurator(ConfiguratorType type, std::string configurator,
88
                       ChainConfigurators chain = ChainConfigurators::No);
89
  ConfiguratorSet const& GetConfigurators(ConfiguratorType type) const;
90
91
  bool HasConfigurators(ConfiguratorType type) const;
92
93
  bool IsGloballyVisible() const
94
0
  {
95
0
    return this->Scope == cm::RuleScope::Global;
96
0
  }
97
98
  cmFileSet* GetOutputFileSet(cmTarget* target,
99
                              cmFileSet const* fileSet) const;
100
101
  // Special properties
102
  cmBTStringRange GetIncludeDirectories() const;
103
104
  cmBTStringRange GetCompileOptions() const;
105
106
  cmBTStringRange GetCompileDefinitions() const;
107
108
  //! Set/Get a property of this rule
109
  void SetProperty(std::string const& prop, cmValue value);
110
  void SetProperty(std::string const& prop, std::nullptr_t)
111
0
  {
112
0
    this->SetProperty(prop, cmValue{ nullptr });
113
0
  }
114
  void RemoveProperty(std::string const& prop)
115
0
  {
116
0
    this->SetProperty(prop, cmValue{ nullptr });
117
0
  }
118
  void SetProperty(std::string const& prop, std::string const& value)
119
0
  {
120
0
    this->SetProperty(prop, cmValue{ value });
121
0
  }
122
  void AppendProperty(std::string const& prop, std::string const& value,
123
                      bool asString = false);
124
  cmValue GetProperty(std::string const& prop) const;
125
126
  void CheckProperty(std::string const& prop, cmMakefile& context) const;
127
128
0
  bool InGeneration() const { return this->Generation; }
129
130
  struct Pattern
131
  {
132
    Pattern(std::string name, std::string value)
133
0
      : Name(std::move(name))
134
0
      , Value(std::move(value))
135
0
    {
136
0
    }
137
138
    std::string Name;
139
    std::string Value;
140
  };
141
  using PatternSet = std::vector<Pattern>;
142
  bool Instantiate(cmTarget const* target, cmFileSet const* fileSet,
143
                   cmFileSet const* outputFileSet, PatternSet& patterns) const;
144
  bool Instantiate(cmTarget const* target, cmFileSet const* fileSet,
145
                   cmFileSet const* outputFileSet, cmSourceFile* source,
146
                   PatternSet& patterns) const;
147
148
protected:
149
  cmRule(cmMakefile& makefile, std::string name, cm::RuleScope scope);
150
  cmRule(cmRule const& parent, cmMakefile& makefile, std::string name,
151
         cm::RuleScope scope);
152
153
private:
154
  // switch context cmRule usage
155
0
  void SwitchMode() const { this->Generation = true; }
156
157
  cmMakefile* Makefile;
158
  std::string Name;
159
  cm::RuleScope Scope = cm::RuleScope::Local;
160
  std::unordered_map<ConfiguratorType, std::string,
161
                     cm::enum_hash<ConfiguratorType>>
162
    Configurators;
163
  std::unordered_map<ConfiguratorType, ConfiguratorSet,
164
                     cm::enum_hash<ConfiguratorType>>
165
    ConfiguratorsChain;
166
  cmPropertyMap Properties;
167
  std::vector<BT<std::string>> IncludeDirectories;
168
  std::vector<BT<std::string>> CompileOptions;
169
  std::vector<BT<std::string>> CompileDefinitions;
170
  // cmRule properties should not be changed during generation phase
171
  // Use mutable field to track current phase independently of state of object
172
  // (const or not)
173
  mutable bool Generation = false;
174
};
175
176
//
177
// cmCustomRule: define a template used to generate custom commands
178
//
179
class cmCustomRule : public cmRule
180
{
181
public:
182
  cmCustomRule(cmMakefile& makefile, std::string name, CustomCommands commands,
183
               std::vector<std::string> outputs,
184
               cm::RuleScope scope = cm::RuleScope::Local);
185
186
  cmCustomRule& operator=(cmCustomRule const&) = delete;
187
188
  /** Get the command lines.  */
189
  CustomCommands const& GetCommands() const override;
190
  /** Get the output files.  */
191
  std::vector<std::string> const& GetOutputs() const override;
192
193
  /** Set/Get the extra files produced by the command.  */
194
  void SetByproducts(std::vector<std::string> byproducts);
195
  std::vector<std::string> const& GetByproducts() const override;
196
197
  /** Set/Get the vector that holds the list of dependencies. */
198
  void SetDepends(std::vector<std::string> depends);
199
  std::vector<std::string> const& GetDepends() const override;
200
  /** Set/Get the file that holds the list of dependencies. */
201
  void SetDepfile(std::string depfile);
202
  std::string const& GetDepfile() const override;
203
204
private:
205
  CustomCommands Commands;
206
  std::vector<std::string> Outputs;
207
  std::vector<std::string> Byproducts;
208
  std::vector<std::string> Depends;
209
  std::string Depfile;
210
};
211
212
//
213
// cmSpecializedRule: rule embedding another rule and enabling properties
214
// customization.
215
//
216
class cmSpecializedRule : public cmRule
217
{
218
public:
219
  cmSpecializedRule(cmMakefile& makefile, std::string name,
220
                    cmRule const& parent,
221
                    cm::RuleScope scope = cm::RuleScope::Local);
222
223
  cmSpecializedRule& operator=(cmSpecializedRule const&) = delete;
224
225
  std::string const& GetParentName() const override;
226
227
  /** Get the command lines.  */
228
  CustomCommands const& GetCommands() const override;
229
  /** Get the output files.  */
230
  std::vector<std::string> const& GetOutputs() const override;
231
232
  /** Get the extra files produced by the command.  */
233
  std::vector<std::string> const& GetByproducts() const override;
234
235
  /** Get the vector that holds the list of dependencies. */
236
  std::vector<std::string> const& GetDepends() const override;
237
  /** Get the file that holds the list of dependencies. */
238
  std::string const& GetDepfile() const override;
239
240
private:
241
  cmRule const& ParentRule;
242
};