/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 | | }; |