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