1 1.1 joerg //===--- Gnu.h - Gnu Tool and ToolChain Implementations ---------*- C++ -*-===// 2 1.1 joerg // 3 1.1 joerg // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 1.1 joerg // See https://llvm.org/LICENSE.txt for license information. 5 1.1 joerg // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 1.1 joerg // 7 1.1 joerg //===----------------------------------------------------------------------===// 8 1.1 joerg 9 1.1 joerg #ifndef LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_GNU_H 10 1.1 joerg #define LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_GNU_H 11 1.1 joerg 12 1.1 joerg #include "Cuda.h" 13 1.1.1.2 joerg #include "ROCm.h" 14 1.1 joerg #include "clang/Driver/Tool.h" 15 1.1 joerg #include "clang/Driver/ToolChain.h" 16 1.1 joerg #include <set> 17 1.1 joerg 18 1.1 joerg namespace clang { 19 1.1 joerg namespace driver { 20 1.1 joerg 21 1.1 joerg struct DetectedMultilibs { 22 1.1 joerg /// The set of multilibs that the detected installation supports. 23 1.1 joerg MultilibSet Multilibs; 24 1.1 joerg 25 1.1 joerg /// The primary multilib appropriate for the given flags. 26 1.1 joerg Multilib SelectedMultilib; 27 1.1 joerg 28 1.1 joerg /// On Biarch systems, this corresponds to the default multilib when 29 1.1 joerg /// targeting the non-default multilib. Otherwise, it is empty. 30 1.1 joerg llvm::Optional<Multilib> BiarchSibling; 31 1.1 joerg }; 32 1.1 joerg 33 1.1 joerg bool findMIPSMultilibs(const Driver &D, const llvm::Triple &TargetTriple, 34 1.1 joerg StringRef Path, const llvm::opt::ArgList &Args, 35 1.1 joerg DetectedMultilibs &Result); 36 1.1 joerg 37 1.1 joerg namespace tools { 38 1.1 joerg 39 1.1.1.2 joerg /// Directly call GNU Binutils' assembler and linker. 40 1.1.1.2 joerg namespace gnutools { 41 1.1.1.2 joerg class LLVM_LIBRARY_VISIBILITY Assembler : public Tool { 42 1.1 joerg public: 43 1.1.1.2 joerg Assembler(const ToolChain &TC) : Tool("GNU::Assembler", "assembler", TC) {} 44 1.1.1.2 joerg 45 1.1.1.2 joerg bool hasIntegratedCPP() const override { return false; } 46 1.1.1.2 joerg 47 1.1.1.2 joerg void ConstructJob(Compilation &C, const JobAction &JA, 48 1.1.1.2 joerg const InputInfo &Output, const InputInfoList &Inputs, 49 1.1.1.2 joerg const llvm::opt::ArgList &TCArgs, 50 1.1.1.2 joerg const char *LinkingOutput) const override; 51 1.1 joerg }; 52 1.1 joerg 53 1.1.1.2 joerg class LLVM_LIBRARY_VISIBILITY Linker : public Tool { 54 1.1 joerg public: 55 1.1.1.2 joerg Linker(const ToolChain &TC) : Tool("GNU::Linker", "linker", TC) {} 56 1.1 joerg 57 1.1 joerg bool hasIntegratedCPP() const override { return false; } 58 1.1.1.2 joerg bool isLinkJob() const override { return true; } 59 1.1 joerg 60 1.1 joerg void ConstructJob(Compilation &C, const JobAction &JA, 61 1.1 joerg const InputInfo &Output, const InputInfoList &Inputs, 62 1.1 joerg const llvm::opt::ArgList &TCArgs, 63 1.1 joerg const char *LinkingOutput) const override; 64 1.1 joerg }; 65 1.1 joerg 66 1.1.1.2 joerg class LLVM_LIBRARY_VISIBILITY StaticLibTool : public Tool { 67 1.1 joerg public: 68 1.1.1.2 joerg StaticLibTool(const ToolChain &TC) 69 1.1.1.2 joerg : Tool("GNU::StaticLibTool", "static-lib-linker", TC) {} 70 1.1 joerg 71 1.1 joerg bool hasIntegratedCPP() const override { return false; } 72 1.1 joerg bool isLinkJob() const override { return true; } 73 1.1 joerg 74 1.1 joerg void ConstructJob(Compilation &C, const JobAction &JA, 75 1.1 joerg const InputInfo &Output, const InputInfoList &Inputs, 76 1.1 joerg const llvm::opt::ArgList &TCArgs, 77 1.1 joerg const char *LinkingOutput) const override; 78 1.1 joerg }; 79 1.1 joerg } // end namespace gnutools 80 1.1 joerg 81 1.1 joerg /// gcc - Generic GCC tool implementations. 82 1.1 joerg namespace gcc { 83 1.1.1.2 joerg class LLVM_LIBRARY_VISIBILITY Common : public Tool { 84 1.1 joerg public: 85 1.1 joerg Common(const char *Name, const char *ShortName, const ToolChain &TC) 86 1.1.1.2 joerg : Tool(Name, ShortName, TC) {} 87 1.1 joerg 88 1.1 joerg // A gcc tool has an "integrated" assembler that it will call to produce an 89 1.1 joerg // object. Let it use that assembler so that we don't have to deal with 90 1.1 joerg // assembly syntax incompatibilities. 91 1.1 joerg bool hasIntegratedAssembler() const override { return true; } 92 1.1 joerg void ConstructJob(Compilation &C, const JobAction &JA, 93 1.1 joerg const InputInfo &Output, const InputInfoList &Inputs, 94 1.1 joerg const llvm::opt::ArgList &TCArgs, 95 1.1 joerg const char *LinkingOutput) const override; 96 1.1 joerg 97 1.1 joerg /// RenderExtraToolArgs - Render any arguments necessary to force 98 1.1 joerg /// the particular tool mode. 99 1.1 joerg virtual void RenderExtraToolArgs(const JobAction &JA, 100 1.1 joerg llvm::opt::ArgStringList &CmdArgs) const = 0; 101 1.1 joerg }; 102 1.1 joerg 103 1.1 joerg class LLVM_LIBRARY_VISIBILITY Preprocessor : public Common { 104 1.1 joerg public: 105 1.1 joerg Preprocessor(const ToolChain &TC) 106 1.1 joerg : Common("gcc::Preprocessor", "gcc preprocessor", TC) {} 107 1.1 joerg 108 1.1 joerg bool hasGoodDiagnostics() const override { return true; } 109 1.1 joerg bool hasIntegratedCPP() const override { return false; } 110 1.1 joerg 111 1.1 joerg void RenderExtraToolArgs(const JobAction &JA, 112 1.1 joerg llvm::opt::ArgStringList &CmdArgs) const override; 113 1.1 joerg }; 114 1.1 joerg 115 1.1 joerg class LLVM_LIBRARY_VISIBILITY Compiler : public Common { 116 1.1 joerg public: 117 1.1 joerg Compiler(const ToolChain &TC) : Common("gcc::Compiler", "gcc frontend", TC) {} 118 1.1 joerg 119 1.1 joerg bool hasGoodDiagnostics() const override { return true; } 120 1.1 joerg bool hasIntegratedCPP() const override { return true; } 121 1.1 joerg 122 1.1 joerg void RenderExtraToolArgs(const JobAction &JA, 123 1.1 joerg llvm::opt::ArgStringList &CmdArgs) const override; 124 1.1 joerg }; 125 1.1 joerg 126 1.1 joerg class LLVM_LIBRARY_VISIBILITY Linker : public Common { 127 1.1 joerg public: 128 1.1 joerg Linker(const ToolChain &TC) : Common("gcc::Linker", "linker (via gcc)", TC) {} 129 1.1 joerg 130 1.1 joerg bool hasIntegratedCPP() const override { return false; } 131 1.1 joerg bool isLinkJob() const override { return true; } 132 1.1 joerg 133 1.1 joerg void RenderExtraToolArgs(const JobAction &JA, 134 1.1 joerg llvm::opt::ArgStringList &CmdArgs) const override; 135 1.1 joerg }; 136 1.1 joerg } // end namespace gcc 137 1.1 joerg } // end namespace tools 138 1.1 joerg 139 1.1 joerg namespace toolchains { 140 1.1 joerg 141 1.1 joerg /// Generic_GCC - A tool chain using the 'gcc' command to perform 142 1.1 joerg /// all subcommands; this relies on gcc translating the majority of 143 1.1 joerg /// command line options. 144 1.1 joerg class LLVM_LIBRARY_VISIBILITY Generic_GCC : public ToolChain { 145 1.1 joerg public: 146 1.1 joerg /// Struct to store and manipulate GCC versions. 147 1.1 joerg /// 148 1.1 joerg /// We rely on assumptions about the form and structure of GCC version 149 1.1 joerg /// numbers: they consist of at most three '.'-separated components, and each 150 1.1 joerg /// component is a non-negative integer except for the last component. For 151 1.1 joerg /// the last component we are very flexible in order to tolerate release 152 1.1 joerg /// candidates or 'x' wildcards. 153 1.1 joerg /// 154 1.1 joerg /// Note that the ordering established among GCCVersions is based on the 155 1.1 joerg /// preferred version string to use. For example we prefer versions without 156 1.1 joerg /// a hard-coded patch number to those with a hard coded patch number. 157 1.1 joerg /// 158 1.1 joerg /// Currently this doesn't provide any logic for textual suffixes to patches 159 1.1 joerg /// in the way that (for example) Debian's version format does. If that ever 160 1.1 joerg /// becomes necessary, it can be added. 161 1.1 joerg struct GCCVersion { 162 1.1 joerg /// The unparsed text of the version. 163 1.1 joerg std::string Text; 164 1.1 joerg 165 1.1 joerg /// The parsed major, minor, and patch numbers. 166 1.1 joerg int Major, Minor, Patch; 167 1.1 joerg 168 1.1 joerg /// The text of the parsed major, and major+minor versions. 169 1.1 joerg std::string MajorStr, MinorStr; 170 1.1 joerg 171 1.1 joerg /// Any textual suffix on the patch number. 172 1.1 joerg std::string PatchSuffix; 173 1.1 joerg 174 1.1 joerg static GCCVersion Parse(StringRef VersionText); 175 1.1 joerg bool isOlderThan(int RHSMajor, int RHSMinor, int RHSPatch, 176 1.1 joerg StringRef RHSPatchSuffix = StringRef()) const; 177 1.1 joerg bool operator<(const GCCVersion &RHS) const { 178 1.1 joerg return isOlderThan(RHS.Major, RHS.Minor, RHS.Patch, RHS.PatchSuffix); 179 1.1 joerg } 180 1.1 joerg bool operator>(const GCCVersion &RHS) const { return RHS < *this; } 181 1.1 joerg bool operator<=(const GCCVersion &RHS) const { return !(*this > RHS); } 182 1.1 joerg bool operator>=(const GCCVersion &RHS) const { return !(*this < RHS); } 183 1.1 joerg }; 184 1.1 joerg 185 1.1 joerg /// This is a class to find a viable GCC installation for Clang to 186 1.1 joerg /// use. 187 1.1 joerg /// 188 1.1 joerg /// This class tries to find a GCC installation on the system, and report 189 1.1 joerg /// information about it. It starts from the host information provided to the 190 1.1 joerg /// Driver, and has logic for fuzzing that where appropriate. 191 1.1 joerg class GCCInstallationDetector { 192 1.1 joerg bool IsValid; 193 1.1 joerg llvm::Triple GCCTriple; 194 1.1 joerg const Driver &D; 195 1.1 joerg 196 1.1 joerg // FIXME: These might be better as path objects. 197 1.1 joerg std::string GCCInstallPath; 198 1.1 joerg std::string GCCParentLibPath; 199 1.1 joerg 200 1.1 joerg /// The primary multilib appropriate for the given flags. 201 1.1 joerg Multilib SelectedMultilib; 202 1.1 joerg /// On Biarch systems, this corresponds to the default multilib when 203 1.1 joerg /// targeting the non-default multilib. Otherwise, it is empty. 204 1.1 joerg llvm::Optional<Multilib> BiarchSibling; 205 1.1 joerg 206 1.1 joerg GCCVersion Version; 207 1.1 joerg 208 1.1 joerg // We retain the list of install paths that were considered and rejected in 209 1.1 joerg // order to print out detailed information in verbose mode. 210 1.1 joerg std::set<std::string> CandidateGCCInstallPaths; 211 1.1 joerg 212 1.1 joerg /// The set of multilibs that the detected installation supports. 213 1.1 joerg MultilibSet Multilibs; 214 1.1 joerg 215 1.1.1.2 joerg // Gentoo-specific toolchain configurations are stored here. 216 1.1.1.2 joerg const std::string GentooConfigDir = "/etc/env.d/gcc"; 217 1.1.1.2 joerg 218 1.1 joerg public: 219 1.1 joerg explicit GCCInstallationDetector(const Driver &D) : IsValid(false), D(D) {} 220 1.1 joerg void init(const llvm::Triple &TargetTriple, const llvm::opt::ArgList &Args, 221 1.1 joerg ArrayRef<std::string> ExtraTripleAliases = None); 222 1.1 joerg 223 1.1 joerg /// Check whether we detected a valid GCC install. 224 1.1 joerg bool isValid() const { return IsValid; } 225 1.1 joerg 226 1.1 joerg /// Get the GCC triple for the detected install. 227 1.1 joerg const llvm::Triple &getTriple() const { return GCCTriple; } 228 1.1 joerg 229 1.1 joerg /// Get the detected GCC installation path. 230 1.1 joerg StringRef getInstallPath() const { return GCCInstallPath; } 231 1.1 joerg 232 1.1 joerg /// Get the detected GCC parent lib path. 233 1.1 joerg StringRef getParentLibPath() const { return GCCParentLibPath; } 234 1.1 joerg 235 1.1 joerg /// Get the detected Multilib 236 1.1 joerg const Multilib &getMultilib() const { return SelectedMultilib; } 237 1.1 joerg 238 1.1 joerg /// Get the whole MultilibSet 239 1.1 joerg const MultilibSet &getMultilibs() const { return Multilibs; } 240 1.1 joerg 241 1.1 joerg /// Get the biarch sibling multilib (if it exists). 242 1.1 joerg /// \return true iff such a sibling exists 243 1.1 joerg bool getBiarchSibling(Multilib &M) const; 244 1.1 joerg 245 1.1 joerg /// Get the detected GCC version string. 246 1.1 joerg const GCCVersion &getVersion() const { return Version; } 247 1.1 joerg 248 1.1 joerg /// Print information about the detected GCC installation. 249 1.1 joerg void print(raw_ostream &OS) const; 250 1.1 joerg 251 1.1 joerg private: 252 1.1 joerg static void 253 1.1 joerg CollectLibDirsAndTriples(const llvm::Triple &TargetTriple, 254 1.1 joerg const llvm::Triple &BiarchTriple, 255 1.1 joerg SmallVectorImpl<StringRef> &LibDirs, 256 1.1 joerg SmallVectorImpl<StringRef> &TripleAliases, 257 1.1 joerg SmallVectorImpl<StringRef> &BiarchLibDirs, 258 1.1 joerg SmallVectorImpl<StringRef> &BiarchTripleAliases); 259 1.1 joerg 260 1.1 joerg void AddDefaultGCCPrefixes(const llvm::Triple &TargetTriple, 261 1.1 joerg SmallVectorImpl<std::string> &Prefixes, 262 1.1 joerg StringRef SysRoot); 263 1.1 joerg 264 1.1 joerg bool ScanGCCForMultilibs(const llvm::Triple &TargetTriple, 265 1.1 joerg const llvm::opt::ArgList &Args, 266 1.1 joerg StringRef Path, 267 1.1 joerg bool NeedsBiarchSuffix = false); 268 1.1 joerg 269 1.1 joerg void ScanLibDirForGCCTriple(const llvm::Triple &TargetArch, 270 1.1 joerg const llvm::opt::ArgList &Args, 271 1.1 joerg const std::string &LibDir, 272 1.1 joerg StringRef CandidateTriple, 273 1.1.1.2 joerg bool NeedsBiarchSuffix, bool GCCDirExists, 274 1.1.1.2 joerg bool GCCCrossDirExists); 275 1.1 joerg 276 1.1 joerg bool ScanGentooConfigs(const llvm::Triple &TargetTriple, 277 1.1 joerg const llvm::opt::ArgList &Args, 278 1.1 joerg const SmallVectorImpl<StringRef> &CandidateTriples, 279 1.1 joerg const SmallVectorImpl<StringRef> &BiarchTriples); 280 1.1 joerg 281 1.1 joerg bool ScanGentooGccConfig(const llvm::Triple &TargetTriple, 282 1.1 joerg const llvm::opt::ArgList &Args, 283 1.1 joerg StringRef CandidateTriple, 284 1.1 joerg bool NeedsBiarchSuffix = false); 285 1.1 joerg }; 286 1.1 joerg 287 1.1 joerg protected: 288 1.1 joerg GCCInstallationDetector GCCInstallation; 289 1.1 joerg CudaInstallationDetector CudaInstallation; 290 1.1.1.2 joerg RocmInstallationDetector RocmInstallation; 291 1.1 joerg 292 1.1 joerg public: 293 1.1 joerg Generic_GCC(const Driver &D, const llvm::Triple &Triple, 294 1.1 joerg const llvm::opt::ArgList &Args); 295 1.1 joerg ~Generic_GCC() override; 296 1.1 joerg 297 1.1 joerg void printVerboseInfo(raw_ostream &OS) const override; 298 1.1 joerg 299 1.1 joerg bool IsUnwindTablesDefault(const llvm::opt::ArgList &Args) const override; 300 1.1 joerg bool isPICDefault() const override; 301 1.1 joerg bool isPIEDefault() const override; 302 1.1 joerg bool isPICDefaultForced() const override; 303 1.1 joerg bool IsIntegratedAssemblerDefault() const override; 304 1.1 joerg llvm::opt::DerivedArgList * 305 1.1 joerg TranslateArgs(const llvm::opt::DerivedArgList &Args, StringRef BoundArch, 306 1.1 joerg Action::OffloadKind DeviceOffloadKind) const override; 307 1.1 joerg 308 1.1 joerg protected: 309 1.1 joerg Tool *getTool(Action::ActionClass AC) const override; 310 1.1 joerg Tool *buildAssembler() const override; 311 1.1 joerg Tool *buildLinker() const override; 312 1.1 joerg 313 1.1 joerg /// \name ToolChain Implementation Helper Functions 314 1.1 joerg /// @{ 315 1.1 joerg 316 1.1 joerg /// Check whether the target triple's architecture is 64-bits. 317 1.1 joerg bool isTarget64Bit() const { return getTriple().isArch64Bit(); } 318 1.1 joerg 319 1.1 joerg /// Check whether the target triple's architecture is 32-bits. 320 1.1 joerg bool isTarget32Bit() const { return getTriple().isArch32Bit(); } 321 1.1 joerg 322 1.1.1.2 joerg void PushPPaths(ToolChain::path_list &PPaths); 323 1.1.1.2 joerg void AddMultilibPaths(const Driver &D, const std::string &SysRoot, 324 1.1.1.2 joerg const std::string &OSLibDir, 325 1.1.1.2 joerg const std::string &MultiarchTriple, 326 1.1.1.2 joerg path_list &Paths); 327 1.1.1.2 joerg void AddMultiarchPaths(const Driver &D, const std::string &SysRoot, 328 1.1.1.2 joerg const std::string &OSLibDir, path_list &Paths); 329 1.1.1.2 joerg void AddMultilibIncludeArgs(const llvm::opt::ArgList &DriverArgs, 330 1.1.1.2 joerg llvm::opt::ArgStringList &CC1Args) const; 331 1.1.1.2 joerg 332 1.1 joerg // FIXME: This should be final, but the CrossWindows toolchain does weird 333 1.1 joerg // things that can't be easily generalized. 334 1.1 joerg void AddClangCXXStdlibIncludeArgs( 335 1.1 joerg const llvm::opt::ArgList &DriverArgs, 336 1.1 joerg llvm::opt::ArgStringList &CC1Args) const override; 337 1.1 joerg 338 1.1 joerg virtual void 339 1.1 joerg addLibCxxIncludePaths(const llvm::opt::ArgList &DriverArgs, 340 1.1 joerg llvm::opt::ArgStringList &CC1Args) const; 341 1.1 joerg virtual void 342 1.1 joerg addLibStdCxxIncludePaths(const llvm::opt::ArgList &DriverArgs, 343 1.1 joerg llvm::opt::ArgStringList &CC1Args) const; 344 1.1 joerg 345 1.1.1.2 joerg bool addGCCLibStdCxxIncludePaths(const llvm::opt::ArgList &DriverArgs, 346 1.1.1.2 joerg llvm::opt::ArgStringList &CC1Args, 347 1.1.1.2 joerg StringRef DebianMultiarch) const; 348 1.1.1.2 joerg 349 1.1.1.2 joerg bool addLibStdCXXIncludePaths(Twine IncludeDir, StringRef Triple, 350 1.1 joerg Twine IncludeSuffix, 351 1.1 joerg const llvm::opt::ArgList &DriverArgs, 352 1.1.1.2 joerg llvm::opt::ArgStringList &CC1Args, 353 1.1.1.2 joerg bool DetectDebian = false) const; 354 1.1 joerg 355 1.1 joerg /// @} 356 1.1 joerg 357 1.1 joerg private: 358 1.1 joerg mutable std::unique_ptr<tools::gcc::Preprocessor> Preprocess; 359 1.1 joerg mutable std::unique_ptr<tools::gcc::Compiler> Compile; 360 1.1 joerg }; 361 1.1 joerg 362 1.1 joerg class LLVM_LIBRARY_VISIBILITY Generic_ELF : public Generic_GCC { 363 1.1 joerg virtual void anchor(); 364 1.1 joerg 365 1.1 joerg public: 366 1.1 joerg Generic_ELF(const Driver &D, const llvm::Triple &Triple, 367 1.1 joerg const llvm::opt::ArgList &Args) 368 1.1 joerg : Generic_GCC(D, Triple, Args) {} 369 1.1 joerg 370 1.1 joerg void addClangTargetOptions(const llvm::opt::ArgList &DriverArgs, 371 1.1 joerg llvm::opt::ArgStringList &CC1Args, 372 1.1 joerg Action::OffloadKind DeviceOffloadKind) const override; 373 1.1.1.2 joerg 374 1.1.1.2 joerg virtual std::string getDynamicLinker(const llvm::opt::ArgList &Args) const { 375 1.1.1.2 joerg return {}; 376 1.1.1.2 joerg } 377 1.1.1.2 joerg 378 1.1.1.2 joerg virtual void addExtraOpts(llvm::opt::ArgStringList &CmdArgs) const {} 379 1.1 joerg }; 380 1.1 joerg 381 1.1 joerg } // end namespace toolchains 382 1.1 joerg } // end namespace driver 383 1.1 joerg } // end namespace clang 384 1.1 joerg 385 1.1 joerg #endif // LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_GNU_H 386