Gnu.h 15 KB

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