Coverage Report

Created: 2026-06-15 07:03

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/CMake/Source/cmExportFileGenerator.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 <functional>
8
#include <iosfwd>
9
#include <map>
10
#include <set>
11
#include <string>
12
#include <vector>
13
14
#include <cm/optional>
15
#include <cm/string_view>
16
17
#include "cmDiagnostics.h"
18
#include "cmGeneratorExpression.h"
19
#include "cmMessageType.h"
20
21
class cmExportSet;
22
class cmGeneratorTarget;
23
class cmGeneratorFileSet;
24
class cmLocalGenerator;
25
26
/** \class cmExportFileGenerator
27
 * \brief Generate files exporting targets from a build or install tree.
28
 *
29
 * cmExportFileGenerator is the interface class for generating export files.
30
 */
31
class cmExportFileGenerator
32
{
33
public:
34
  cmExportFileGenerator();
35
0
  virtual ~cmExportFileGenerator() = default;
36
37
  struct ExportInfo
38
  {
39
    std::vector<std::string> Files;
40
    std::set<std::string> Sets;
41
    std::set<std::string> Namespaces;
42
  };
43
44
  /** Set the full path to the export file to generate.  */
45
  void SetExportFile(char const* mainFile);
46
  std::string const& GetMainExportFileName() const;
47
48
  /** Set the namespace in which to place exported target names.  */
49
0
  void SetNamespace(std::string const& ns) { this->Namespace = ns; }
50
0
  std::string GetNamespace() const { return this->Namespace; }
51
52
  /** Add a configuration to be exported.  */
53
  void AddConfiguration(std::string const& config);
54
55
  /** Create and actually generate the export file.  Returns whether there was
56
      an error.  */
57
  bool GenerateImportFile();
58
59
protected:
60
  using ImportPropertyMap = std::map<std::string, std::string>;
61
  using ImportFileSetPropertyMap = std::map<std::string, ImportPropertyMap>;
62
63
  // Collect properties with detailed information about targets beyond
64
  // their location on disk.
65
  void SetImportDetailProperties(std::string const& config,
66
                                 std::string const& suffix,
67
                                 cmGeneratorTarget const* target,
68
                                 ImportPropertyMap& properties);
69
70
  enum class ImportLinkPropertyTargetNames
71
  {
72
    Yes,
73
    No,
74
  };
75
  template <typename T>
76
  void SetImportLinkProperty(std::string const& suffix,
77
                             cmGeneratorTarget const* target,
78
                             std::string const& propName,
79
                             std::vector<T> const& entries,
80
                             ImportPropertyMap& properties,
81
                             ImportLinkPropertyTargetNames targetNames);
82
83
  /** Generate the export file to the given output stream.  Returns whether
84
      there was an error.  */
85
  virtual bool GenerateImportFile(std::ostream& os) = 0;
86
87
  /** Each subclass knows how to generate its kind of export file.  */
88
  virtual bool GenerateMainFile(std::ostream& os) = 0;
89
90
  /** Generate per-configuration target information to the given output
91
      stream.  */
92
  virtual void GenerateImportConfig(std::ostream& os,
93
                                    std::string const& config);
94
95
  /** Each subclass knows where the target files are located.  */
96
  virtual void GenerateImportTargetsConfig(std::ostream& os,
97
                                           std::string const& config,
98
                                           std::string const& suffix) = 0;
99
100
  /** Record a target referenced by an exported target. */
101
  virtual bool NoteLinkedTarget(cmGeneratorTarget const* target,
102
                                std::string const& linkedName,
103
                                cmGeneratorTarget const* linkedTarget);
104
105
  /** Each subclass knows how to deal with a target that is  missing from an
106
   *  export set.  */
107
  virtual void HandleMissingTarget(std::string& link_libs,
108
                                   cmGeneratorTarget const* depender,
109
                                   cmGeneratorTarget* dependee) = 0;
110
111
  /** Complain when a duplicate target is encountered.  */
112
  virtual void ComplainAboutDuplicateTarget(
113
    std::string const& targetName) const = 0;
114
115
  virtual cm::string_view GetImportPrefixWithSlash() const = 0;
116
117
  void AddImportPrefix(std::string& exportDirs) const;
118
119
  void PopulateInterfaceProperty(std::string const& propName,
120
                                 cmGeneratorTarget const* target,
121
                                 ImportPropertyMap& properties) const;
122
  void PopulateInterfaceProperty(std::string const& propName,
123
                                 cmGeneratorTarget const* target,
124
                                 cmGeneratorExpression::PreprocessContext,
125
                                 ImportPropertyMap& properties);
126
  void PopulateFileSetInterfaceProperty(
127
    std::string const& propName, cmGeneratorTarget const* target,
128
    cmGeneratorFileSet const* fileSet,
129
    cmGeneratorExpression::PreprocessContext, ImportPropertyMap& properties);
130
  bool PopulateInterfaceLinkLibrariesProperty(
131
    cmGeneratorTarget const* target, cmGeneratorExpression::PreprocessContext,
132
    ImportPropertyMap& properties);
133
134
  bool PopulateInterfaceProperties(
135
    cmGeneratorTarget const* target,
136
    std::string const& includesDestinationDirs,
137
    cmGeneratorExpression::PreprocessContext preprocessRule,
138
    ImportPropertyMap& properties);
139
140
  bool PopulateFileSetInterfaceProperties(
141
    cmGeneratorTarget const* target, cmGeneratorFileSet const* fileSet,
142
    cmGeneratorExpression::PreprocessContext preprocessRule,
143
    ImportPropertyMap& properties);
144
145
  virtual void IssueMessage(MessageType type,
146
                            std::string const& message) const = 0;
147
  virtual void IssueDiagnostic(cmDiagnosticCategory category,
148
                               std::string const& message) const = 0;
149
150
  void ReportError(std::string const& errorMessage) const
151
0
  {
152
0
    this->IssueMessage(MessageType::FATAL_ERROR, errorMessage);
153
0
  }
154
155
  /** Find the set of export files and the unique namespace (if any) for a
156
   *  target. */
157
  virtual ExportInfo FindExportInfo(cmGeneratorTarget const* target) const = 0;
158
159
  enum FreeTargetsReplace
160
  {
161
    ReplaceFreeTargets,
162
    NoReplaceFreeTargets
163
  };
164
165
  void ResolveTargetsInGeneratorExpressions(
166
    std::string& input, cmGeneratorTarget const* target,
167
    FreeTargetsReplace replace = NoReplaceFreeTargets);
168
169
0
  virtual cmExportSet* GetExportSet() const { return nullptr; }
170
171
  virtual void ReplaceInstallPrefix(std::string& input) const;
172
173
  virtual std::string InstallNameDir(cmGeneratorTarget const* target,
174
                                     std::string const& config) = 0;
175
176
  /** Get the temporary location of the config-agnostic C++ module file.  */
177
  virtual std::string GetCxxModuleFile(std::string const& name) const = 0;
178
179
  virtual std::string GetCxxModulesDirectory() const = 0;
180
  virtual void GenerateCxxModuleConfigInformation(std::string const&,
181
                                                  std::ostream& os) const = 0;
182
183
  bool AddTargetNamespace(std::string& input, cmGeneratorTarget const* target,
184
                          cmLocalGenerator const* lg);
185
186
  static std::string PropertyConfigSuffix(std::string const& config);
187
188
  // The namespace in which the exports are placed in the generated file.
189
  std::string Namespace;
190
191
  // The set of configurations to export.
192
  std::vector<std::string> Configurations;
193
194
  // The file to generate.
195
  std::string MainImportFile;
196
  std::string FileDir;
197
  std::string FileBase;
198
  std::string FileExt;
199
  bool AppendMode = false;
200
201
  // The set of targets included in the export.
202
  std::set<cmGeneratorTarget const*> ExportedTargets;
203
204
  std::vector<std::string> MissingTargets;
205
206
  std::set<cmGeneratorTarget const*> ExternalTargets;
207
208
private:
209
  void PopulateInterfaceProperty(std::string const& propName,
210
                                 std::string const& outputName,
211
                                 cmGeneratorTarget const* target,
212
                                 cmGeneratorExpression::PreprocessContext,
213
                                 ImportPropertyMap& properties);
214
215
  void PopulateCompatibleInterfaceProperties(
216
    cmGeneratorTarget const* target, ImportPropertyMap& properties) const;
217
  void PopulateCustomTransitiveInterfaceProperties(
218
    cmGeneratorTarget const* target,
219
    cmGeneratorExpression::PreprocessContext preprocessRule,
220
    ImportPropertyMap& properties);
221
  bool PopulateCxxModuleExportProperties(
222
    cmGeneratorTarget const* gte, ImportPropertyMap& properties,
223
    cmGeneratorExpression::PreprocessContext ctx,
224
    std::string const& includesDestinationDirs, std::string& errorMessage);
225
  bool PopulateExportProperties(cmGeneratorTarget const* gte,
226
                                ImportPropertyMap& properties,
227
                                std::string& errorMessage) const;
228
229
  void ResolveTargetsInGeneratorExpression(std::string& input,
230
                                           cmGeneratorTarget const* target,
231
                                           cmLocalGenerator const* lg);
232
};
233
234
extern template void cmExportFileGenerator::SetImportLinkProperty<std::string>(
235
  std::string const&, cmGeneratorTarget const*, std::string const&,
236
  std::vector<std::string> const&, ImportPropertyMap& properties,
237
  ImportLinkPropertyTargetNames);
238
239
extern template void cmExportFileGenerator::SetImportLinkProperty<cmLinkItem>(
240
  std::string const&, cmGeneratorTarget const*, std::string const&,
241
  std::vector<cmLinkItem> const&, ImportPropertyMap& properties,
242
  ImportLinkPropertyTargetNames);
243
244
/** Walk a generator expression and rewrite the target-name slot of each
245
    `$<TARGET_PROPERTY:>`, `$<TARGET_NAME:>`, `$<LINK_ONLY:>`, and
246
    `$<COMPILE_ONLY:>` construct via the provided callback.  The callback
247
    receives the bare target name; if it mutates the name and returns true,
248
    the helper splices the new name back into the genex. Returns the
249
    parse-level error message, if an error was encountered. Callers handle
250
    install-prefix substitution and error reporting themselves. This is used
251
    by the cmExportFileGenerator hierarchy, as well as the cmSbomBuilder
252
    hierarchy.  */
253
cm::optional<std::string> cmResolveTargetsInGeneratorExpression(
254
  std::string& input,
255
  std::function<bool(std::string& name)> const& addTargetNamespace);