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 <memory>
9 #include <set>
10 #include <string>
11 #include <utility>
12 #include <vector>
13 
14 #include "cmsys/RegularExpression.hxx"
15 
16 #include "cmListFileCache.h"
17 #include "cmValue.h"
18 
19 class cmGeneratorTarget;
20 class cmGlobalGenerator;
21 class cmMakefile;
22 class cmOrderDirectories;
23 class cmake;
24 
25 /** \class cmComputeLinkInformation
26  * \brief Compute link information for a target in one configuration.
27  */
28 class cmComputeLinkInformation
29 {
30 public:
31   cmComputeLinkInformation(cmGeneratorTarget const* target,
32                            const std::string& config);
33   cmComputeLinkInformation(const cmComputeLinkInformation&) = delete;
34   cmComputeLinkInformation& operator=(const cmComputeLinkInformation&) =
35     delete;
36   ~cmComputeLinkInformation();
37   bool Compute();
38 
39   enum class ItemIsPath
40   {
41     No,
42     Yes,
43   };
44 
45   enum class ItemIsObject
46   {
47     No,
48     Yes,
49   };
50 
51   struct Item
52   {
53     Item() = default;
54     Item(BT<std::string> v, ItemIsPath isPath,
55          ItemIsObject isObject = ItemIsObject::No,
56          cmGeneratorTarget const* target = nullptr)
ValueItem57       : Value(std::move(v))
58       , IsPath(isPath)
59       , IsObject(isObject)
60       , Target(target)
61     {
62     }
63     BT<std::string> Value;
64     ItemIsPath IsPath = ItemIsPath::Yes;
65     ItemIsObject IsObject = ItemIsObject::No;
66     cmGeneratorTarget const* Target = nullptr;
67   };
68   using ItemVector = std::vector<Item>;
69   void AppendValues(std::string& result, std::vector<BT<std::string>>& values);
70   ItemVector const& GetItems() const;
71   std::vector<std::string> const& GetDirectories() const;
72   std::vector<BT<std::string>> GetDirectoriesWithBacktraces();
73   std::vector<std::string> const& GetDepends() const;
74   std::vector<std::string> const& GetFrameworkPaths() const;
75   std::set<std::string> const& GetFrameworkPathsEmitted() const;
GetLinkLanguage()76   std::string GetLinkLanguage() const { return this->LinkLanguage; }
77   std::vector<std::string> const& GetRuntimeSearchPath() const;
GetRuntimeFlag()78   std::string const& GetRuntimeFlag() const { return this->RuntimeFlag; }
GetRuntimeSep()79   std::string const& GetRuntimeSep() const { return this->RuntimeSep; }
80   void GetRPath(std::vector<std::string>& runtimeDirs, bool for_install) const;
81   std::string GetRPathString(bool for_install) const;
82   std::string GetChrpathString() const;
83   std::set<cmGeneratorTarget const*> const& GetSharedLibrariesLinked() const;
GetRuntimeDLLs()84   std::vector<cmGeneratorTarget const*> const& GetRuntimeDLLs() const
85   {
86     return this->RuntimeDLLs;
87   }
88 
GetLibLinkFileFlag()89   std::string const& GetLibLinkFileFlag() const
90   {
91     return this->LibLinkFileFlag;
92   }
93 
GetObjLinkFileFlag()94   std::string const& GetObjLinkFileFlag() const
95   {
96     return this->ObjLinkFileFlag;
97   }
98 
GetRPathLinkFlag()99   std::string const& GetRPathLinkFlag() const { return this->RPathLinkFlag; }
100   std::string GetRPathLinkString() const;
101 
GetConfig()102   std::string GetConfig() const { return this->Config; }
103 
GetTarget()104   const cmGeneratorTarget* GetTarget() { return this->Target; }
105 
106 private:
107   void AddItem(BT<std::string> const& item, const cmGeneratorTarget* tgt,
108                ItemIsObject isObject = ItemIsObject::No);
109   void AddSharedDepItem(BT<std::string> const& item,
110                         cmGeneratorTarget const* tgt);
111   void AddRuntimeDLL(cmGeneratorTarget const* tgt);
112 
113   // Output information.
114   ItemVector Items;
115   std::vector<std::string> Directories;
116   std::vector<std::string> Depends;
117   std::vector<std::string> FrameworkPaths;
118   std::vector<std::string> RuntimeSearchPath;
119   std::set<cmGeneratorTarget const*> SharedLibrariesLinked;
120   std::vector<cmGeneratorTarget const*> RuntimeDLLs;
121 
122   // Context information.
123   cmGeneratorTarget const* const Target;
124   cmMakefile* const Makefile;
125   cmGlobalGenerator* const GlobalGenerator;
126   cmake* const CMakeInstance;
127 
128   // Configuration information.
129   std::string const Config;
130   std::string LinkLanguage;
131 
132   // Modes for dealing with dependent shared libraries.
133   enum SharedDepMode
134   {
135     SharedDepModeNone,   // Drop
136     SharedDepModeDir,    // List dir in -rpath-link flag
137     SharedDepModeLibDir, // List dir in linker search path
138     SharedDepModeLink    // List file on link line
139   };
140 
141   cmValue LoaderFlag;
142   std::string LibLinkFlag;
143   std::string LibLinkFileFlag;
144   std::string ObjLinkFileFlag;
145   std::string LibLinkSuffix;
146   std::string RuntimeFlag;
147   std::string RuntimeSep;
148   std::string RuntimeAlways;
149   std::string RPathLinkFlag;
150   SharedDepMode SharedDependencyMode;
151 
152   enum LinkType
153   {
154     LinkUnknown,
155     LinkStatic,
156     LinkShared
157   };
158   void SetCurrentLinkType(LinkType lt);
159 
160   // Link type adjustment.
161   void ComputeLinkTypeInfo();
162   LinkType StartLinkType;
163   LinkType CurrentLinkType;
164   std::string StaticLinkTypeFlag;
165   std::string SharedLinkTypeFlag;
166 
167   // Link item parsing.
168   void ComputeItemParserInfo();
169   std::vector<std::string> StaticLinkExtensions;
170   std::vector<std::string> SharedLinkExtensions;
171   std::vector<std::string> LinkExtensions;
172   std::set<std::string> LinkPrefixes;
173   cmsys::RegularExpression ExtractStaticLibraryName;
174   cmsys::RegularExpression ExtractSharedLibraryName;
175   cmsys::RegularExpression ExtractAnyLibraryName;
176   std::string SharedRegexString;
177   void AddLinkPrefix(std::string const& p);
178   void AddLinkExtension(std::string const& e, LinkType type);
179   std::string CreateExtensionRegex(std::vector<std::string> const& exts,
180                                    LinkType type);
181   std::string NoCaseExpression(std::string const& str);
182 
183   // Handling of link items.
184   void AddTargetItem(BT<std::string> const& item,
185                      const cmGeneratorTarget* target);
186   void AddFullItem(BT<std::string> const& item, ItemIsObject isObject);
187   bool CheckImplicitDirItem(std::string const& item);
188   void AddUserItem(BT<std::string> const& item, bool pathNotKnown);
189   void AddFrameworkItem(std::string const& item);
190   void DropDirectoryItem(std::string const& item);
191   bool CheckSharedLibNoSOName(std::string const& item);
192   void AddSharedLibNoSOName(std::string const& item);
193   void HandleBadFullItem(std::string const& item, std::string const& file);
194 
195   // Framework info.
196   void ComputeFrameworkInfo();
197   void AddFrameworkPath(std::string const& p);
198   std::set<std::string> FrameworkPathsEmitted;
199   cmsys::RegularExpression SplitFramework;
200 
201   // Linker search path computation.
202   std::unique_ptr<cmOrderDirectories> OrderLinkerSearchPath;
203   bool FinishLinkerSearchDirectories();
204   void PrintLinkPolicyDiagnosis(std::ostream&);
205 
206   // Implicit link libraries and directories for linker language.
207   void LoadImplicitLinkInfo();
208   void AddImplicitLinkInfo();
209   void AddImplicitLinkInfo(std::string const& lang);
210   void AddRuntimeLinkLibrary(std::string const& lang);
211   std::set<std::string> ImplicitLinkDirs;
212   std::set<std::string> ImplicitLinkLibs;
213 
214   // Additional paths configured by the runtime linker
215   std::vector<std::string> RuntimeLinkDirs;
216 
217   // Linker search path compatibility mode.
218   std::set<std::string> OldLinkDirMask;
219   std::vector<std::string> OldLinkDirItems;
220   std::vector<std::string> OldUserFlagItems;
221   std::set<std::string> CMP0060WarnItems;
222   // Dependent library path computation.
223   std::unique_ptr<cmOrderDirectories> OrderDependentRPath;
224   // Runtime path computation.
225   std::unique_ptr<cmOrderDirectories> OrderRuntimeSearchPath;
226 
227   bool OldLinkDirMode;
228   bool OpenBSD;
229   bool LinkDependsNoShared;
230   bool RuntimeUseChrpath;
231   bool NoSONameUsesPath;
232   bool LinkWithRuntimePath;
233   bool LinkTypeEnabled;
234   bool ArchivesMayBeShared;
235   bool CMP0060Warn;
236 
237   void AddLibraryRuntimeInfo(std::string const& fullPath,
238                              const cmGeneratorTarget* target);
239   void AddLibraryRuntimeInfo(std::string const& fullPath);
240 };
241