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