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