1 //===--- ToolChains.cpp - ToolChain Implementations ---------------------*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "ToolChains.h"
12 #include "clang/Driver/Arg.h"
13 #include "clang/Driver/ArgList.h"
14 #include "clang/Driver/Driver.h"
15 #include "clang/Driver/DriverDiagnostic.h"
16 #include "clang/Driver/HostInfo.h"
17 #include "clang/Driver/Option.h"
19 #include "llvm/ADT/StringExtras.h"
20 #include "llvm/Support/raw_ostream.h"
21 #include "llvm/System/Path.h"
23 #include <cstdlib> // ::getenv
25 using namespace clang::driver
;
26 using namespace clang::driver::toolchains
;
28 /// Darwin_X86 - Darwin tool chain for i386 and x86_64.
30 Darwin_X86::Darwin_X86(const HostInfo
&Host
, const llvm::Triple
& Triple
,
31 const unsigned (&_DarwinVersion
)[3],
32 const unsigned (&_GCCVersion
)[3])
33 : ToolChain(Host
, Triple
) {
34 DarwinVersion
[0] = _DarwinVersion
[0];
35 DarwinVersion
[1] = _DarwinVersion
[1];
36 DarwinVersion
[2] = _DarwinVersion
[2];
37 GCCVersion
[0] = _GCCVersion
[0];
38 GCCVersion
[1] = _GCCVersion
[1];
39 GCCVersion
[2] = _GCCVersion
[2];
41 llvm::raw_string_ostream(MacosxVersionMin
)
42 << "10." << DarwinVersion
[0] - 4 << '.' << DarwinVersion
[1];
44 ToolChainDir
= "i686-apple-darwin";
45 ToolChainDir
+= llvm::utostr(DarwinVersion
[0]);
47 ToolChainDir
+= llvm::utostr(GCCVersion
[0]);
49 ToolChainDir
+= llvm::utostr(GCCVersion
[1]);
51 ToolChainDir
+= llvm::utostr(GCCVersion
[2]);
54 if (getArchName() == "x86_64") {
55 Path
= getHost().getDriver().Dir
;
56 Path
+= "/../lib/gcc/";
57 Path
+= getToolChainDir();
59 getFilePaths().push_back(Path
);
61 Path
= "/usr/lib/gcc/";
62 Path
+= getToolChainDir();
64 getFilePaths().push_back(Path
);
67 Path
= getHost().getDriver().Dir
;
68 Path
+= "/../lib/gcc/";
69 Path
+= getToolChainDir();
70 getFilePaths().push_back(Path
);
72 Path
= "/usr/lib/gcc/";
73 Path
+= getToolChainDir();
74 getFilePaths().push_back(Path
);
76 Path
= getHost().getDriver().Dir
;
77 Path
+= "/../libexec/gcc/";
78 Path
+= getToolChainDir();
79 getProgramPaths().push_back(Path
);
81 Path
= "/usr/libexec/gcc/";
82 Path
+= getToolChainDir();
83 getProgramPaths().push_back(Path
);
85 Path
= getHost().getDriver().Dir
;
86 Path
+= "/../libexec";
87 getProgramPaths().push_back(Path
);
89 getProgramPaths().push_back(getHost().getDriver().Dir
);
92 Darwin_X86::~Darwin_X86() {
93 // Free tool implementations.
94 for (llvm::DenseMap
<unsigned, Tool
*>::iterator
95 it
= Tools
.begin(), ie
= Tools
.end(); it
!= ie
; ++it
)
99 Tool
&Darwin_X86::SelectTool(const Compilation
&C
,
100 const JobAction
&JA
) const {
101 Action::ActionClass Key
;
102 if (getHost().getDriver().ShouldUseClangCompiler(C
, JA
, getArchName()))
103 Key
= Action::AnalyzeJobClass
;
107 Tool
*&T
= Tools
[Key
];
110 case Action::InputClass
:
111 case Action::BindArchClass
:
112 assert(0 && "Invalid tool kind.");
113 case Action::PreprocessJobClass
:
114 T
= new tools::darwin::Preprocess(*this); break;
115 case Action::AnalyzeJobClass
:
116 T
= new tools::Clang(*this); break;
117 case Action::PrecompileJobClass
:
118 case Action::CompileJobClass
:
119 T
= new tools::darwin::Compile(*this); break;
120 case Action::AssembleJobClass
:
121 T
= new tools::darwin::Assemble(*this); break;
122 case Action::LinkJobClass
:
123 T
= new tools::darwin::Link(*this, MacosxVersionMin
.c_str()); break;
124 case Action::LipoJobClass
:
125 T
= new tools::darwin::Lipo(*this); break;
132 DerivedArgList
*Darwin_X86::TranslateArgs(InputArgList
&Args
) const {
133 DerivedArgList
*DAL
= new DerivedArgList(Args
, false);
134 const OptTable
&Opts
= getHost().getDriver().getOpts();
136 // FIXME: We really want to get out of the tool chain level argument
137 // translation business, as it makes the driver functionality much
138 // more opaque. For now, we follow gcc closely solely for the
139 // purpose of easily achieving feature parity & testability. Once we
140 // have something that works, we should reevaluate each translation
141 // and try to push it down into tool specific logic.
144 Args
.getLastArg(options::OPT_mmacosx_version_min_EQ
, false);
146 Args
.getLastArg(options::OPT_miphoneos_version_min_EQ
, false);
147 if (OSXVersion
&& iPhoneVersion
) {
148 getHost().getDriver().Diag(clang::diag::err_drv_argument_not_allowed_with
)
149 << OSXVersion
->getAsString(Args
)
150 << iPhoneVersion
->getAsString(Args
);
151 } else if (!OSXVersion
&& !iPhoneVersion
) {
152 // Chose the default version based on the arch.
154 // FIXME: This will need to be fixed when we merge in arm support.
156 // Look for MACOSX_DEPLOYMENT_TARGET, otherwise use the version
158 const char *Version
= ::getenv("MACOSX_DEPLOYMENT_TARGET");
160 Version
= MacosxVersionMin
.c_str();
161 const Option
*O
= Opts
.getOption(options::OPT_mmacosx_version_min_EQ
);
162 DAL
->append(DAL
->MakeJoinedArg(0, O
, Version
));
165 for (ArgList::iterator it
= Args
.begin(), ie
= Args
.end(); it
!= ie
; ++it
) {
168 if (A
->getOption().matches(options::OPT_Xarch__
)) {
169 // FIXME: Canonicalize name.
170 if (getArchName() != A
->getValue(Args
, 0))
173 // FIXME: The arg is leaked here, and we should have a nicer
174 // interface for this.
175 unsigned Prev
, Index
= Prev
= A
->getIndex() + 1;
176 Arg
*XarchArg
= Opts
.ParseOneArg(Args
, Index
);
178 // If the argument parsing failed or more than one argument was
179 // consumed, the -Xarch_ argument's parameter tried to consume
180 // extra arguments. Emit an error and ignore.
182 // We also want to disallow any options which would alter the
183 // driver behavior; that isn't going to work in our model. We
184 // use isDriverOption() as an approximation, although things
185 // like -O4 are going to slip through.
186 if (!XarchArg
|| Index
> Prev
+ 1 ||
187 XarchArg
->getOption().isDriverOption()) {
188 getHost().getDriver().Diag(clang::diag::err_drv_invalid_Xarch_argument
)
189 << A
->getAsString(Args
);
193 XarchArg
->setBaseArg(A
);
197 // Sob. These is strictly gcc compatible for the time being. Apple
198 // gcc translates options twice, which means that self-expanding
199 // options add duplicates.
200 options::ID id
= A
->getOption().getId();
206 case options::OPT_mkernel
:
207 case options::OPT_fapple_kext
:
209 DAL
->append(DAL
->MakeFlagArg(A
, Opts
.getOption(options::OPT_static
)));
210 DAL
->append(DAL
->MakeFlagArg(A
, Opts
.getOption(options::OPT_static
)));
213 case options::OPT_dependency_file
:
214 DAL
->append(DAL
->MakeSeparateArg(A
, Opts
.getOption(options::OPT_MF
),
218 case options::OPT_gfull
:
219 DAL
->append(DAL
->MakeFlagArg(A
, Opts
.getOption(options::OPT_g_Flag
)));
220 DAL
->append(DAL
->MakeFlagArg(A
,
221 Opts
.getOption(options::OPT_fno_eliminate_unused_debug_symbols
)));
224 case options::OPT_gused
:
225 DAL
->append(DAL
->MakeFlagArg(A
, Opts
.getOption(options::OPT_g_Flag
)));
226 DAL
->append(DAL
->MakeFlagArg(A
,
227 Opts
.getOption(options::OPT_feliminate_unused_debug_symbols
)));
230 case options::OPT_fterminated_vtables
:
231 case options::OPT_findirect_virtual_calls
:
232 DAL
->append(DAL
->MakeFlagArg(A
,
233 Opts
.getOption(options::OPT_fapple_kext
)));
234 DAL
->append(DAL
->MakeFlagArg(A
, Opts
.getOption(options::OPT_static
)));
237 case options::OPT_shared
:
238 DAL
->append(DAL
->MakeFlagArg(A
, Opts
.getOption(options::OPT_dynamiclib
)));
241 case options::OPT_fconstant_cfstrings
:
242 DAL
->append(DAL
->MakeFlagArg(A
,
243 Opts
.getOption(options::OPT_mconstant_cfstrings
)));
246 case options::OPT_fno_constant_cfstrings
:
247 DAL
->append(DAL
->MakeFlagArg(A
,
248 Opts
.getOption(options::OPT_mno_constant_cfstrings
)));
251 case options::OPT_Wnonportable_cfstrings
:
252 DAL
->append(DAL
->MakeFlagArg(A
,
253 Opts
.getOption(options::OPT_mwarn_nonportable_cfstrings
)));
256 case options::OPT_Wno_nonportable_cfstrings
:
257 DAL
->append(DAL
->MakeFlagArg(A
,
258 Opts
.getOption(options::OPT_mno_warn_nonportable_cfstrings
)));
261 case options::OPT_fpascal_strings
:
262 DAL
->append(DAL
->MakeFlagArg(A
,
263 Opts
.getOption(options::OPT_mpascal_strings
)));
266 case options::OPT_fno_pascal_strings
:
267 DAL
->append(DAL
->MakeFlagArg(A
,
268 Opts
.getOption(options::OPT_mno_pascal_strings
)));
273 // FIXME: Actually, gcc always adds this, but it is filtered for
274 // duplicates somewhere. This also changes the order of things, so
276 if (getArchName() == "x86_64")
277 if (!Args
.hasArg(options::OPT_m64
, false))
278 DAL
->append(DAL
->MakeFlagArg(0, Opts
.getOption(options::OPT_m64
)));
280 if (!Args
.hasArg(options::OPT_mtune_EQ
, false))
281 DAL
->append(DAL
->MakeJoinedArg(0, Opts
.getOption(options::OPT_mtune_EQ
),
287 bool Darwin_X86::IsMathErrnoDefault() const {
291 bool Darwin_X86::IsUnwindTablesDefault() const {
292 // FIXME: Gross; we should probably have some separate target
293 // definition, possibly even reusing the one in clang.
294 return getArchName() == "x86_64";
297 const char *Darwin_X86::GetDefaultRelocationModel() const {
301 const char *Darwin_X86::GetForcedPicModel() const {
302 if (getArchName() == "x86_64")
307 /// Generic_GCC - A tool chain using the 'gcc' command to perform
308 /// all subcommands; this relies on gcc translating the majority of
309 /// command line options.
311 Generic_GCC::Generic_GCC(const HostInfo
&Host
, const llvm::Triple
& Triple
)
312 : ToolChain(Host
, Triple
)
314 std::string
Path(getHost().getDriver().Dir
);
315 Path
+= "/../libexec";
316 getProgramPaths().push_back(Path
);
318 getProgramPaths().push_back(getHost().getDriver().Dir
);
321 Generic_GCC::~Generic_GCC() {
322 // Free tool implementations.
323 for (llvm::DenseMap
<unsigned, Tool
*>::iterator
324 it
= Tools
.begin(), ie
= Tools
.end(); it
!= ie
; ++it
)
328 Tool
&Generic_GCC::SelectTool(const Compilation
&C
,
329 const JobAction
&JA
) const {
330 Action::ActionClass Key
;
331 if (getHost().getDriver().ShouldUseClangCompiler(C
, JA
, getArchName()))
332 Key
= Action::AnalyzeJobClass
;
336 Tool
*&T
= Tools
[Key
];
339 case Action::InputClass
:
340 case Action::BindArchClass
:
341 assert(0 && "Invalid tool kind.");
342 case Action::PreprocessJobClass
:
343 T
= new tools::gcc::Preprocess(*this); break;
344 case Action::PrecompileJobClass
:
345 T
= new tools::gcc::Precompile(*this); break;
346 case Action::AnalyzeJobClass
:
347 T
= new tools::Clang(*this); break;
348 case Action::CompileJobClass
:
349 T
= new tools::gcc::Compile(*this); break;
350 case Action::AssembleJobClass
:
351 T
= new tools::gcc::Assemble(*this); break;
352 case Action::LinkJobClass
:
353 T
= new tools::gcc::Link(*this); break;
355 // This is a bit ungeneric, but the only platform using a driver
357 case Action::LipoJobClass
:
358 T
= new tools::darwin::Lipo(*this); break;
365 bool Generic_GCC::IsMathErrnoDefault() const {
369 bool Generic_GCC::IsUnwindTablesDefault() const {
370 // FIXME: Gross; we should probably have some separate target
371 // definition, possibly even reusing the one in clang.
372 return getArchName() == "x86_64";
375 const char *Generic_GCC::GetDefaultRelocationModel() const {
379 const char *Generic_GCC::GetForcedPicModel() const {
383 DerivedArgList
*Generic_GCC::TranslateArgs(InputArgList
&Args
) const {
384 return new DerivedArgList(Args
, true);
387 /// OpenBSD - OpenBSD tool chain which can call as(1) and ld(1) directly.
389 OpenBSD::OpenBSD(const HostInfo
&Host
, const llvm::Triple
& Triple
)
390 : Generic_GCC(Host
, Triple
) {
391 getFilePaths().push_back(getHost().getDriver().Dir
+ "/../lib");
392 getFilePaths().push_back("/usr/lib");
395 Tool
&OpenBSD::SelectTool(const Compilation
&C
, const JobAction
&JA
) const {
396 Action::ActionClass Key
;
397 if (getHost().getDriver().ShouldUseClangCompiler(C
, JA
, getArchName()))
398 Key
= Action::AnalyzeJobClass
;
402 Tool
*&T
= Tools
[Key
];
405 case Action::AssembleJobClass
:
406 T
= new tools::openbsd::Assemble(*this); break;
407 case Action::LinkJobClass
:
408 T
= new tools::openbsd::Link(*this); break;
410 T
= &Generic_GCC::SelectTool(C
, JA
);
417 /// FreeBSD - FreeBSD tool chain which can call as(1) and ld(1) directly.
419 FreeBSD::FreeBSD(const HostInfo
&Host
, const llvm::Triple
& Triple
, bool Lib32
)
420 : Generic_GCC(Host
, Triple
) {
422 getFilePaths().push_back(getHost().getDriver().Dir
+ "/../lib32");
423 getFilePaths().push_back("/usr/lib32");
425 getFilePaths().push_back(getHost().getDriver().Dir
+ "/../lib");
426 getFilePaths().push_back("/usr/lib");
430 Tool
&FreeBSD::SelectTool(const Compilation
&C
, const JobAction
&JA
) const {
431 Action::ActionClass Key
;
432 if (getHost().getDriver().ShouldUseClangCompiler(C
, JA
, getArchName()))
433 Key
= Action::AnalyzeJobClass
;
437 Tool
*&T
= Tools
[Key
];
440 case Action::AssembleJobClass
:
441 T
= new tools::freebsd::Assemble(*this); break;
442 case Action::LinkJobClass
:
443 T
= new tools::freebsd::Link(*this); break;
445 T
= &Generic_GCC::SelectTool(C
, JA
);
452 /// Linux toolchain (very bare-bones at the moment).
454 Linux::Linux(const HostInfo
&Host
, const llvm::Triple
& Triple
)
455 : Generic_GCC(Host
, Triple
) {
456 getFilePaths().push_back(getHost().getDriver().Dir
+ "/../lib/clang/1.0/");
457 getFilePaths().push_back("/lib/");
458 getFilePaths().push_back("/usr/lib/");
459 // FIXME: Figure out some way to get gcc's libdir
460 // (e.g. /usr/lib/gcc/i486-linux-gnu/4.3/ for Ubuntu 32-bit); we need
461 // crtbegin.o/crtend.o/etc., and want static versions of various
462 // libraries. If we had our own crtbegin.o/crtend.o/etc, we could probably
463 // get away with using shared versions in /usr/lib, though.
464 // We could fall back to the approach we used for includes (a massive
465 // list), but that's messy at best.
468 /// DragonFly - DragonFly tool chain which can call as(1) and ld(1) directly.
470 DragonFly::DragonFly(const HostInfo
&Host
, const llvm::Triple
& Triple
)
471 : Generic_GCC(Host
, Triple
) {
473 // Path mangling to find libexec
474 std::string
Path(getHost().getDriver().Dir
);
476 Path
+= "/../libexec";
477 getProgramPaths().push_back(Path
);
478 getProgramPaths().push_back(getHost().getDriver().Dir
);
480 getFilePaths().push_back(getHost().getDriver().Dir
+ "/../lib");
481 getFilePaths().push_back("/usr/lib");
482 getFilePaths().push_back("/usr/lib/gcc41");
485 Tool
&DragonFly::SelectTool(const Compilation
&C
, const JobAction
&JA
) const {
486 Action::ActionClass Key
;
487 if (getHost().getDriver().ShouldUseClangCompiler(C
, JA
, getArchName()))
488 Key
= Action::AnalyzeJobClass
;
492 Tool
*&T
= Tools
[Key
];
495 case Action::AssembleJobClass
:
496 T
= new tools::dragonfly::Assemble(*this); break;
497 case Action::LinkJobClass
:
498 T
= new tools::dragonfly::Link(*this); break;
500 T
= &Generic_GCC::SelectTool(C
, JA
);