Coverage Report

Created: 2026-03-12 06:35

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/CMake/Source/cmComputeLinkInformation.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 "cmsys/RegularExpression.hxx"
15
16
#include "cmComputeLinkDepends.h"
17
#include "cmListFileCache.h"
18
#include "cmValue.h"
19
20
class cmGeneratorTarget;
21
class cmGlobalGenerator;
22
class cmMakefile;
23
class cmOrderDirectories;
24
class cmSourceFile;
25
class cmake;
26
27
/** \class cmComputeLinkInformation
28
 * \brief Compute link information for a target in one configuration.
29
 */
30
class cmComputeLinkInformation
31
{
32
private:
33
  class FeatureDescriptor;
34
35
public:
36
  cmComputeLinkInformation(cmGeneratorTarget const* target,
37
                           std::string const& config);
38
  cmComputeLinkInformation(cmComputeLinkInformation const&) = delete;
39
  cmComputeLinkInformation& operator=(cmComputeLinkInformation const&) =
40
    delete;
41
  ~cmComputeLinkInformation();
42
  bool Compute();
43
44
  enum class ItemIsPath
45
  {
46
    No,
47
    Yes,
48
  };
49
50
  struct Item
51
  {
52
    Item(BT<std::string> v, ItemIsPath isPath,
53
         cmGeneratorTarget const* target = nullptr,
54
         cmSourceFile const* objectSource = nullptr,
55
         FeatureDescriptor const* feature = nullptr)
56
0
      : Value(std::move(v))
57
0
      , IsPath(isPath)
58
0
      , Target(target)
59
0
      , ObjectSource(objectSource)
60
0
      , Feature(feature)
61
0
    {
62
0
    }
63
    BT<std::string> Value;
64
    ItemIsPath IsPath = ItemIsPath::No;
65
    cmGeneratorTarget const* Target = nullptr;
66
    // The source file representing the external object (used when linking
67
    // `$<TARGET_OBJECTS>`)
68
    cmSourceFile const* ObjectSource = nullptr;
69
70
0
    bool HasFeature() const { return this->Feature != nullptr; }
71
    std::string const& GetFeatureName() const
72
0
    {
73
0
      return HasFeature() ? this->Feature->Name
74
0
                          : cmComputeLinkDepends::LinkEntry::DEFAULT;
75
0
    }
76
77
    BT<std::string> GetFormattedItem(std::string const& path) const
78
0
    {
79
0
      return { this->Feature
80
0
                 ? this->Feature->GetDecoratedItem(path, this->IsPath)
81
0
                 : path,
82
0
               Value.Backtrace };
83
0
    }
84
85
  private:
86
    FeatureDescriptor const* Feature = nullptr;
87
  };
88
  using ItemVector = std::vector<Item>;
89
  void AppendValues(std::string& result, std::vector<BT<std::string>>& values);
90
  ItemVector const& GetItems() const;
91
  std::vector<std::string> const& GetDirectories() const;
92
  std::vector<BT<std::string>> GetDirectoriesWithBacktraces();
93
  std::vector<std::string> const& GetDepends() const;
94
  std::vector<std::string> const& GetFrameworkPaths() const;
95
  std::set<std::string> const& GetFrameworkPathsEmitted() const;
96
  std::vector<std::string> const& GetXcFrameworkHeaderPaths() const;
97
0
  std::string GetLinkLanguage() const { return this->LinkLanguage; }
98
  std::vector<std::string> const& GetRuntimeSearchPath() const;
99
0
  std::string const& GetRuntimeFlag() const { return this->RuntimeFlag; }
100
0
  std::string const& GetRuntimeSep() const { return this->RuntimeSep; }
101
  void GetRPath(std::vector<std::string>& runtimeDirs, bool for_install) const;
102
  std::string GetRPathString(bool for_install) const;
103
  std::string GetChrpathString() const;
104
  std::set<cmGeneratorTarget const*> const& GetSharedLibrariesLinked() const;
105
  std::vector<cmGeneratorTarget const*> const& GetExternalObjectTargets()
106
    const;
107
  std::vector<cmGeneratorTarget const*> const& GetRuntimeDLLs() const
108
0
  {
109
0
    return this->RuntimeDLLs;
110
0
  }
111
112
  std::string const& GetLibLinkFileFlag() const
113
0
  {
114
0
    return this->LibLinkFileFlag;
115
0
  }
116
117
  std::string const& GetObjLinkFileFlag() const
118
0
  {
119
0
    return this->ObjLinkFileFlag;
120
0
  }
121
122
0
  std::string const& GetRPathLinkFlag() const { return this->RPathLinkFlag; }
123
  std::string GetRPathLinkString() const;
124
125
0
  std::string GetConfig() const { return this->Config; }
126
127
0
  cmGeneratorTarget const* GetTarget() { return this->Target; }
128
129
private:
130
  using LinkEntry = cmComputeLinkDepends::LinkEntry;
131
132
  void AddItem(LinkEntry const& entry);
133
  void AddSharedDepItem(LinkEntry const& entry);
134
  void AddRuntimeDLL(cmGeneratorTarget const* tgt);
135
136
  // Output information.
137
  ItemVector Items;
138
  std::vector<std::string> Directories;
139
  std::vector<std::string> Depends;
140
  std::vector<std::string> FrameworkPaths;
141
  std::vector<std::string> XcFrameworkHeaderPaths;
142
  std::vector<std::string> RuntimeSearchPath;
143
  std::set<cmGeneratorTarget const*> SharedLibrariesLinked;
144
  std::vector<cmGeneratorTarget const*> ExternalObjectTargets;
145
  std::vector<cmGeneratorTarget const*> RuntimeDLLs;
146
147
  // Context information.
148
  cmGeneratorTarget const* const Target;
149
  cmMakefile* const Makefile;
150
  cmGlobalGenerator* const GlobalGenerator;
151
  cmake* const CMakeInstance;
152
153
  // Configuration information.
154
  std::string const Config;
155
  std::string LinkLanguage;
156
157
  // Modes for dealing with dependent shared libraries.
158
  enum SharedDepMode
159
  {
160
    SharedDepModeNone,   // Drop
161
    SharedDepModeDir,    // List dir in -rpath-link flag
162
    SharedDepModeLibDir, // List dir in linker search path
163
    SharedDepModeLink    // List file on link line
164
  };
165
166
  cmValue LoaderFlag;
167
  std::string LibLinkFlag;
168
  std::string LibLinkFileFlag;
169
  std::string ObjLinkFileFlag;
170
  std::string LibLinkSuffix;
171
  std::string RuntimeFlag;
172
  std::string RuntimeSep;
173
  std::string RuntimeAlways;
174
  std::string RPathLinkFlag;
175
  SharedDepMode SharedDependencyMode;
176
177
  enum LinkType
178
  {
179
    LinkUnknown,
180
    LinkStatic,
181
    LinkShared
182
  };
183
  void SetCurrentLinkType(LinkType lt);
184
185
  // Link type adjustment.
186
  void ComputeLinkTypeInfo();
187
  LinkType StartLinkType;
188
  LinkType CurrentLinkType;
189
  std::string StaticLinkTypeFlag;
190
  std::string SharedLinkTypeFlag;
191
192
  // Link item parsing.
193
  void ComputeItemParserInfo();
194
  std::vector<std::string> StaticLinkExtensions;
195
  std::vector<std::string> SharedLinkExtensions;
196
  std::vector<std::string> LinkExtensions;
197
  std::set<std::string> LinkPrefixes;
198
  cmsys::RegularExpression ExtractStaticLibraryName;
199
  cmsys::RegularExpression ExtractSharedLibraryName;
200
  cmsys::RegularExpression ExtractAnyLibraryName;
201
  std::string SharedRegexString;
202
  void AddLinkPrefix(std::string const& p);
203
  void AddLinkExtension(std::string const& e, LinkType type);
204
  std::string CreateExtensionRegex(std::vector<std::string> const& exts,
205
                                   LinkType type);
206
  std::string NoCaseExpression(std::string const& str);
207
208
  // Handling of link items.
209
  void AddTargetItem(LinkEntry const& entry);
210
  void AddFullItem(LinkEntry const& entry);
211
  bool CheckImplicitDirItem(LinkEntry const& entry);
212
  void AddUserItem(LinkEntry const& entry);
213
  void AddFrameworkItem(LinkEntry const& entry);
214
  void AddXcFrameworkItem(LinkEntry const& entry);
215
  void DropDirectoryItem(BT<std::string> const& item);
216
  bool CheckSharedLibNoSOName(LinkEntry const& entry);
217
  void AddSharedLibNoSOName(LinkEntry const& entry);
218
219
  // Framework info.
220
  void ComputeFrameworkInfo();
221
  void AddFrameworkPath(std::string const& p);
222
  std::set<std::string> FrameworkPathsEmitted;
223
224
  void AddXcFrameworkHeaderPath(std::string const& p);
225
226
  // Linker search path computation.
227
  std::unique_ptr<cmOrderDirectories> OrderLinkerSearchPath;
228
229
  void AddExternalObjectTargets();
230
231
  // Implicit link libraries and directories for linker language.
232
  void LoadImplicitLinkInfo();
233
  void AddImplicitLinkInfo();
234
  void AddImplicitLinkInfo(std::string const& lang);
235
  void AddRuntimeLinkLibrary(std::string const& lang);
236
  std::set<std::string> ImplicitLinkDirs;
237
  std::set<std::string> ImplicitLinkLibs;
238
239
  // Additional paths configured by the runtime linker
240
  std::vector<std::string> RuntimeLinkDirs;
241
242
  // Dependent library path computation.
243
  std::unique_ptr<cmOrderDirectories> OrderDependentRPath;
244
  // Runtime path computation.
245
  std::unique_ptr<cmOrderDirectories> OrderRuntimeSearchPath;
246
247
  bool IsOpenBSD;
248
  bool LinkDependsNoShared;
249
  bool RuntimeUseChrpath;
250
  bool NoSONameUsesPath;
251
  bool LinkWithRuntimePath;
252
  bool LinkTypeEnabled;
253
  bool ArchivesMayBeShared;
254
255
  void AddLibraryRuntimeInfo(std::string const& fullPath,
256
                             cmGeneratorTarget const* target);
257
  void AddLibraryRuntimeInfo(std::string const& fullPath);
258
259
  class FeatureDescriptor
260
  {
261
  public:
262
0
    FeatureDescriptor() = default;
263
264
    std::string const Name;
265
    bool const Supported = false;
266
    std::string const Prefix;
267
    std::string const Suffix;
268
    std::string GetDecoratedItem(std::string const& library,
269
                                 ItemIsPath isPath) const;
270
    std::string GetDecoratedItem(std::string const& library,
271
                                 std::string const& linkItem,
272
                                 std::string const& defaultValue,
273
                                 ItemIsPath isPath) const;
274
275
  protected:
276
    FeatureDescriptor(std::string name, std::string itemFormat);
277
    FeatureDescriptor(std::string name, std::string itemPathFormat,
278
                      std::string itemNameFormat);
279
    FeatureDescriptor(std::string name, std::string prefix,
280
                      std::string itemPathFormat, std::string itemNameFormat,
281
                      std::string suffix);
282
283
    FeatureDescriptor(std::string name, std::string prefix, std::string suffix,
284
                      bool isGroup);
285
286
  private:
287
    std::string ItemPathFormat;
288
    std::string ItemNameFormat;
289
  };
290
291
  class LibraryFeatureDescriptor : public FeatureDescriptor
292
  {
293
  public:
294
    LibraryFeatureDescriptor(std::string name, std::string itemFormat);
295
    LibraryFeatureDescriptor(std::string name, std::string itemPathFormat,
296
                             std::string itemNameFormat);
297
    LibraryFeatureDescriptor(std::string name, std::string prefix,
298
                             std::string itemPathFormat,
299
                             std::string itemNameFormat, std::string suffix);
300
  };
301
  std::map<std::string, FeatureDescriptor> LibraryFeatureDescriptors;
302
  bool AddLibraryFeature(std::string const& feature);
303
  FeatureDescriptor const& GetLibraryFeature(std::string const& feature) const;
304
  FeatureDescriptor const* FindLibraryFeature(
305
    std::string const& feature) const;
306
307
  class GroupFeatureDescriptor : public FeatureDescriptor
308
  {
309
  public:
310
    GroupFeatureDescriptor(std::string name, std::string prefix,
311
                           std::string suffix);
312
  };
313
  std::map<std::string, FeatureDescriptor> GroupFeatureDescriptors;
314
  FeatureDescriptor const& GetGroupFeature(std::string const& feature);
315
};