blob: 63b629f9ec2f8868d5bda05448f8b9f13e3b5fbc [file] [log] [blame]
Daniel Dunbar39176082009-03-20 00:20:03 +00001//===--- ToolChains.cpp - ToolChain Implementations ---------------------*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "ToolChains.h"
11
Daniel Dunbarf3cad362009-03-25 04:13:45 +000012#include "clang/Driver/Arg.h"
13#include "clang/Driver/ArgList.h"
Daniel Dunbarc50b00d2009-03-23 16:15:50 +000014#include "clang/Driver/Driver.h"
Daniel Dunbar4e7e9cf2009-03-25 06:12:34 +000015#include "clang/Driver/DriverDiagnostic.h"
Daniel Dunbarc50b00d2009-03-23 16:15:50 +000016#include "clang/Driver/HostInfo.h"
Daniel Dunbar4e7e9cf2009-03-25 06:12:34 +000017#include "clang/Driver/Option.h"
Daniel Dunbarc50b00d2009-03-23 16:15:50 +000018
19#include "llvm/ADT/StringExtras.h"
Daniel Dunbarec069ed2009-03-25 06:58:31 +000020#include "llvm/Support/raw_ostream.h"
Daniel Dunbarc50b00d2009-03-23 16:15:50 +000021#include "llvm/System/Path.h"
22
Daniel Dunbarf36a06a2009-04-10 21:00:07 +000023#include <cstdlib> // ::getenv
24
Daniel Dunbar39176082009-03-20 00:20:03 +000025using namespace clang::driver;
26using namespace clang::driver::toolchains;
27
Daniel Dunbarf3955282009-09-04 18:34:51 +000028/// Darwin - Darwin tool chain for i386 and x86_64.
Daniel Dunbar8eddb3f2009-03-20 00:57:52 +000029
Daniel Dunbarf3955282009-09-04 18:34:51 +000030Darwin::Darwin(const HostInfo &Host, const llvm::Triple& Triple,
31 const unsigned (&_DarwinVersion)[3],
32 const unsigned (&_GCCVersion)[3])
Daniel Dunbarcb8ab232009-05-22 02:53:45 +000033 : ToolChain(Host, Triple) {
Daniel Dunbarc50b00d2009-03-23 16:15:50 +000034 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];
40
Daniel Dunbar02633b52009-03-26 16:23:12 +000041 llvm::raw_string_ostream(MacosxVersionMin)
42 << "10." << DarwinVersion[0] - 4 << '.' << DarwinVersion[1];
43
Daniel Dunbarc50b00d2009-03-23 16:15:50 +000044 ToolChainDir = "i686-apple-darwin";
45 ToolChainDir += llvm::utostr(DarwinVersion[0]);
46 ToolChainDir += "/";
47 ToolChainDir += llvm::utostr(GCCVersion[0]);
48 ToolChainDir += '.';
49 ToolChainDir += llvm::utostr(GCCVersion[1]);
50 ToolChainDir += '.';
51 ToolChainDir += llvm::utostr(GCCVersion[2]);
52
53 std::string Path;
54 if (getArchName() == "x86_64") {
55 Path = getHost().getDriver().Dir;
56 Path += "/../lib/gcc/";
57 Path += getToolChainDir();
58 Path += "/x86_64";
59 getFilePaths().push_back(Path);
60
61 Path = "/usr/lib/gcc/";
62 Path += getToolChainDir();
63 Path += "/x86_64";
64 getFilePaths().push_back(Path);
65 }
66
67 Path = getHost().getDriver().Dir;
68 Path += "/../lib/gcc/";
69 Path += getToolChainDir();
70 getFilePaths().push_back(Path);
71
72 Path = "/usr/lib/gcc/";
73 Path += getToolChainDir();
74 getFilePaths().push_back(Path);
75
76 Path = getHost().getDriver().Dir;
77 Path += "/../libexec/gcc/";
78 Path += getToolChainDir();
79 getProgramPaths().push_back(Path);
80
81 Path = "/usr/libexec/gcc/";
82 Path += getToolChainDir();
83 getProgramPaths().push_back(Path);
84
Daniel Dunbar82fa7c52009-03-24 04:07:10 +000085 Path = getHost().getDriver().Dir;
86 Path += "/../libexec";
87 getProgramPaths().push_back(Path);
88
Daniel Dunbarc50b00d2009-03-23 16:15:50 +000089 getProgramPaths().push_back(getHost().getDriver().Dir);
90}
91
Daniel Dunbarf3955282009-09-04 18:34:51 +000092Darwin::~Darwin() {
Daniel Dunbar8eddb3f2009-03-20 00:57:52 +000093 // Free tool implementations.
94 for (llvm::DenseMap<unsigned, Tool*>::iterator
95 it = Tools.begin(), ie = Tools.end(); it != ie; ++it)
96 delete it->second;
97}
98
Daniel Dunbarf3955282009-09-04 18:34:51 +000099Tool &Darwin::SelectTool(const Compilation &C, const JobAction &JA) const {
Daniel Dunbar8eddb3f2009-03-20 00:57:52 +0000100 Action::ActionClass Key;
Daniel Dunbaraf80e1f2009-03-24 18:57:02 +0000101 if (getHost().getDriver().ShouldUseClangCompiler(C, JA, getArchName()))
Daniel Dunbar8eddb3f2009-03-20 00:57:52 +0000102 Key = Action::AnalyzeJobClass;
103 else
104 Key = JA.getKind();
105
106 Tool *&T = Tools[Key];
107 if (!T) {
108 switch (Key) {
109 case Action::InputClass:
110 case Action::BindArchClass:
111 assert(0 && "Invalid tool kind.");
112 case Action::PreprocessJobClass:
Daniel Dunbar9120f172009-03-29 22:27:40 +0000113 T = new tools::darwin::Preprocess(*this); break;
Daniel Dunbar8eddb3f2009-03-20 00:57:52 +0000114 case Action::AnalyzeJobClass:
115 T = new tools::Clang(*this); break;
Daniel Dunbar9120f172009-03-29 22:27:40 +0000116 case Action::PrecompileJobClass:
Daniel Dunbar8eddb3f2009-03-20 00:57:52 +0000117 case Action::CompileJobClass:
Daniel Dunbar9120f172009-03-29 22:27:40 +0000118 T = new tools::darwin::Compile(*this); break;
Daniel Dunbar8eddb3f2009-03-20 00:57:52 +0000119 case Action::AssembleJobClass:
Daniel Dunbar8cac5f72009-03-20 16:06:39 +0000120 T = new tools::darwin::Assemble(*this); break;
Daniel Dunbar8eddb3f2009-03-20 00:57:52 +0000121 case Action::LinkJobClass:
Daniel Dunbar8f289622009-09-04 17:39:02 +0000122 T = new tools::darwin::Link(*this); break;
Daniel Dunbar8eddb3f2009-03-20 00:57:52 +0000123 case Action::LipoJobClass:
124 T = new tools::darwin::Lipo(*this); break;
125 }
126 }
127
128 return *T;
129}
130
Daniel Dunbarf3955282009-09-04 18:34:51 +0000131DerivedArgList *Darwin::TranslateArgs(InputArgList &Args) const {
Daniel Dunbar4e7e9cf2009-03-25 06:12:34 +0000132 DerivedArgList *DAL = new DerivedArgList(Args, false);
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000133 const OptTable &Opts = getHost().getDriver().getOpts();
134
135 // FIXME: We really want to get out of the tool chain level argument
136 // translation business, as it makes the driver functionality much
137 // more opaque. For now, we follow gcc closely solely for the
138 // purpose of easily achieving feature parity & testability. Once we
139 // have something that works, we should reevaluate each translation
140 // and try to push it down into tool specific logic.
141
Daniel Dunbarff8857a2009-04-10 20:11:50 +0000142 Arg *OSXVersion =
143 Args.getLastArg(options::OPT_mmacosx_version_min_EQ, false);
144 Arg *iPhoneVersion =
145 Args.getLastArg(options::OPT_miphoneos_version_min_EQ, false);
146 if (OSXVersion && iPhoneVersion) {
147 getHost().getDriver().Diag(clang::diag::err_drv_argument_not_allowed_with)
148 << OSXVersion->getAsString(Args)
149 << iPhoneVersion->getAsString(Args);
150 } else if (!OSXVersion && !iPhoneVersion) {
151 // Chose the default version based on the arch.
152 //
153 // FIXME: This will need to be fixed when we merge in arm support.
Daniel Dunbarf36a06a2009-04-10 21:00:07 +0000154
155 // Look for MACOSX_DEPLOYMENT_TARGET, otherwise use the version
156 // from the host.
157 const char *Version = ::getenv("MACOSX_DEPLOYMENT_TARGET");
158 if (!Version)
159 Version = MacosxVersionMin.c_str();
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000160 const Option *O = Opts.getOption(options::OPT_mmacosx_version_min_EQ);
Daniel Dunbarf36a06a2009-04-10 21:00:07 +0000161 DAL->append(DAL->MakeJoinedArg(0, O, Version));
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000162 }
Daniel Dunbar4e7e9cf2009-03-25 06:12:34 +0000163
164 for (ArgList::iterator it = Args.begin(), ie = Args.end(); it != ie; ++it) {
165 Arg *A = *it;
166
167 if (A->getOption().matches(options::OPT_Xarch__)) {
168 // FIXME: Canonicalize name.
169 if (getArchName() != A->getValue(Args, 0))
170 continue;
171
172 // FIXME: The arg is leaked here, and we should have a nicer
173 // interface for this.
Daniel Dunbar4e7e9cf2009-03-25 06:12:34 +0000174 unsigned Prev, Index = Prev = A->getIndex() + 1;
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000175 Arg *XarchArg = Opts.ParseOneArg(Args, Index);
Daniel Dunbar4e7e9cf2009-03-25 06:12:34 +0000176
177 // If the argument parsing failed or more than one argument was
178 // consumed, the -Xarch_ argument's parameter tried to consume
179 // extra arguments. Emit an error and ignore.
180 //
181 // We also want to disallow any options which would alter the
182 // driver behavior; that isn't going to work in our model. We
183 // use isDriverOption() as an approximation, although things
184 // like -O4 are going to slip through.
185 if (!XarchArg || Index > Prev + 1 ||
186 XarchArg->getOption().isDriverOption()) {
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000187 getHost().getDriver().Diag(clang::diag::err_drv_invalid_Xarch_argument)
Daniel Dunbar4e7e9cf2009-03-25 06:12:34 +0000188 << A->getAsString(Args);
189 continue;
190 }
191
Daniel Dunbar478edc22009-03-29 22:29:05 +0000192 XarchArg->setBaseArg(A);
Daniel Dunbar4e7e9cf2009-03-25 06:12:34 +0000193 A = XarchArg;
194 }
195
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000196 // Sob. These is strictly gcc compatible for the time being. Apple
197 // gcc translates options twice, which means that self-expanding
198 // options add duplicates.
199 options::ID id = A->getOption().getId();
200 switch (id) {
201 default:
202 DAL->append(A);
203 break;
204
205 case options::OPT_mkernel:
206 case options::OPT_fapple_kext:
207 DAL->append(A);
Daniel Dunbar478edc22009-03-29 22:29:05 +0000208 DAL->append(DAL->MakeFlagArg(A, Opts.getOption(options::OPT_static)));
209 DAL->append(DAL->MakeFlagArg(A, Opts.getOption(options::OPT_static)));
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000210 break;
211
212 case options::OPT_dependency_file:
Daniel Dunbar478edc22009-03-29 22:29:05 +0000213 DAL->append(DAL->MakeSeparateArg(A, Opts.getOption(options::OPT_MF),
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000214 A->getValue(Args)));
215 break;
216
217 case options::OPT_gfull:
Daniel Dunbar478edc22009-03-29 22:29:05 +0000218 DAL->append(DAL->MakeFlagArg(A, Opts.getOption(options::OPT_g_Flag)));
219 DAL->append(DAL->MakeFlagArg(A,
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000220 Opts.getOption(options::OPT_fno_eliminate_unused_debug_symbols)));
221 break;
222
223 case options::OPT_gused:
Daniel Dunbar478edc22009-03-29 22:29:05 +0000224 DAL->append(DAL->MakeFlagArg(A, Opts.getOption(options::OPT_g_Flag)));
225 DAL->append(DAL->MakeFlagArg(A,
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000226 Opts.getOption(options::OPT_feliminate_unused_debug_symbols)));
227 break;
228
229 case options::OPT_fterminated_vtables:
230 case options::OPT_findirect_virtual_calls:
Daniel Dunbar478edc22009-03-29 22:29:05 +0000231 DAL->append(DAL->MakeFlagArg(A,
232 Opts.getOption(options::OPT_fapple_kext)));
233 DAL->append(DAL->MakeFlagArg(A, Opts.getOption(options::OPT_static)));
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000234 break;
235
236 case options::OPT_shared:
Daniel Dunbar478edc22009-03-29 22:29:05 +0000237 DAL->append(DAL->MakeFlagArg(A, Opts.getOption(options::OPT_dynamiclib)));
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000238 break;
239
240 case options::OPT_fconstant_cfstrings:
Daniel Dunbar478edc22009-03-29 22:29:05 +0000241 DAL->append(DAL->MakeFlagArg(A,
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000242 Opts.getOption(options::OPT_mconstant_cfstrings)));
243 break;
244
245 case options::OPT_fno_constant_cfstrings:
Daniel Dunbar478edc22009-03-29 22:29:05 +0000246 DAL->append(DAL->MakeFlagArg(A,
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000247 Opts.getOption(options::OPT_mno_constant_cfstrings)));
248 break;
249
250 case options::OPT_Wnonportable_cfstrings:
Daniel Dunbar478edc22009-03-29 22:29:05 +0000251 DAL->append(DAL->MakeFlagArg(A,
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000252 Opts.getOption(options::OPT_mwarn_nonportable_cfstrings)));
253 break;
254
255 case options::OPT_Wno_nonportable_cfstrings:
Daniel Dunbar478edc22009-03-29 22:29:05 +0000256 DAL->append(DAL->MakeFlagArg(A,
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000257 Opts.getOption(options::OPT_mno_warn_nonportable_cfstrings)));
258 break;
259
260 case options::OPT_fpascal_strings:
Daniel Dunbar478edc22009-03-29 22:29:05 +0000261 DAL->append(DAL->MakeFlagArg(A,
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000262 Opts.getOption(options::OPT_mpascal_strings)));
263 break;
264
265 case options::OPT_fno_pascal_strings:
Daniel Dunbar478edc22009-03-29 22:29:05 +0000266 DAL->append(DAL->MakeFlagArg(A,
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000267 Opts.getOption(options::OPT_mno_pascal_strings)));
268 break;
269 }
Daniel Dunbar4e7e9cf2009-03-25 06:12:34 +0000270 }
271
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000272 // FIXME: Actually, gcc always adds this, but it is filtered for
273 // duplicates somewhere. This also changes the order of things, so
274 // look it up.
275 if (getArchName() == "x86_64")
276 if (!Args.hasArg(options::OPT_m64, false))
Daniel Dunbar478edc22009-03-29 22:29:05 +0000277 DAL->append(DAL->MakeFlagArg(0, Opts.getOption(options::OPT_m64)));
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000278
279 if (!Args.hasArg(options::OPT_mtune_EQ, false))
Daniel Dunbar478edc22009-03-29 22:29:05 +0000280 DAL->append(DAL->MakeJoinedArg(0, Opts.getOption(options::OPT_mtune_EQ),
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000281 "core2"));
282
Daniel Dunbar4e7e9cf2009-03-25 06:12:34 +0000283 return DAL;
Daniel Dunbar8eddb3f2009-03-20 00:57:52 +0000284}
285
Daniel Dunbarf3955282009-09-04 18:34:51 +0000286bool Darwin::IsMathErrnoDefault() const {
Daniel Dunbar8eddb3f2009-03-20 00:57:52 +0000287 return false;
288}
289
Daniel Dunbarf3955282009-09-04 18:34:51 +0000290bool Darwin::IsUnwindTablesDefault() const {
Daniel Dunbar8eddb3f2009-03-20 00:57:52 +0000291 // FIXME: Gross; we should probably have some separate target
292 // definition, possibly even reusing the one in clang.
293 return getArchName() == "x86_64";
294}
295
Daniel Dunbarf3955282009-09-04 18:34:51 +0000296const char *Darwin::GetDefaultRelocationModel() const {
Daniel Dunbar8eddb3f2009-03-20 00:57:52 +0000297 return "pic";
298}
299
Daniel Dunbarf3955282009-09-04 18:34:51 +0000300const char *Darwin::GetForcedPicModel() const {
Daniel Dunbar8eddb3f2009-03-20 00:57:52 +0000301 if (getArchName() == "x86_64")
302 return "pic";
303 return 0;
304}
305
Daniel Dunbar39176082009-03-20 00:20:03 +0000306/// Generic_GCC - A tool chain using the 'gcc' command to perform
307/// all subcommands; this relies on gcc translating the majority of
308/// command line options.
309
Daniel Dunbarcb8ab232009-05-22 02:53:45 +0000310Generic_GCC::Generic_GCC(const HostInfo &Host, const llvm::Triple& Triple)
311 : ToolChain(Host, Triple)
Daniel Dunbarc50b00d2009-03-23 16:15:50 +0000312{
Daniel Dunbar82fa7c52009-03-24 04:07:10 +0000313 std::string Path(getHost().getDriver().Dir);
314 Path += "/../libexec";
315 getProgramPaths().push_back(Path);
316
Daniel Dunbarc50b00d2009-03-23 16:15:50 +0000317 getProgramPaths().push_back(getHost().getDriver().Dir);
318}
319
Daniel Dunbar39176082009-03-20 00:20:03 +0000320Generic_GCC::~Generic_GCC() {
321 // Free tool implementations.
322 for (llvm::DenseMap<unsigned, Tool*>::iterator
323 it = Tools.begin(), ie = Tools.end(); it != ie; ++it)
324 delete it->second;
325}
326
327Tool &Generic_GCC::SelectTool(const Compilation &C,
328 const JobAction &JA) const {
329 Action::ActionClass Key;
Daniel Dunbaraf80e1f2009-03-24 18:57:02 +0000330 if (getHost().getDriver().ShouldUseClangCompiler(C, JA, getArchName()))
Daniel Dunbar39176082009-03-20 00:20:03 +0000331 Key = Action::AnalyzeJobClass;
332 else
333 Key = JA.getKind();
334
335 Tool *&T = Tools[Key];
336 if (!T) {
337 switch (Key) {
Daniel Dunbar8eddb3f2009-03-20 00:57:52 +0000338 case Action::InputClass:
339 case Action::BindArchClass:
Daniel Dunbar39176082009-03-20 00:20:03 +0000340 assert(0 && "Invalid tool kind.");
341 case Action::PreprocessJobClass:
342 T = new tools::gcc::Preprocess(*this); break;
343 case Action::PrecompileJobClass:
344 T = new tools::gcc::Precompile(*this); break;
345 case Action::AnalyzeJobClass:
346 T = new tools::Clang(*this); break;
347 case Action::CompileJobClass:
348 T = new tools::gcc::Compile(*this); break;
349 case Action::AssembleJobClass:
350 T = new tools::gcc::Assemble(*this); break;
351 case Action::LinkJobClass:
352 T = new tools::gcc::Link(*this); break;
Daniel Dunbar8eddb3f2009-03-20 00:57:52 +0000353
354 // This is a bit ungeneric, but the only platform using a driver
355 // driver is Darwin.
356 case Action::LipoJobClass:
357 T = new tools::darwin::Lipo(*this); break;
Daniel Dunbar39176082009-03-20 00:20:03 +0000358 }
359 }
360
361 return *T;
362}
363
Daniel Dunbarf3955282009-09-04 18:34:51 +0000364bool Generic_GCC::IsMathErrnoDefault() const {
Daniel Dunbar39176082009-03-20 00:20:03 +0000365 return true;
366}
367
368bool Generic_GCC::IsUnwindTablesDefault() const {
Daniel Dunbar8eddb3f2009-03-20 00:57:52 +0000369 // FIXME: Gross; we should probably have some separate target
370 // definition, possibly even reusing the one in clang.
Daniel Dunbar39176082009-03-20 00:20:03 +0000371 return getArchName() == "x86_64";
372}
373
374const char *Generic_GCC::GetDefaultRelocationModel() const {
375 return "static";
376}
377
378const char *Generic_GCC::GetForcedPicModel() const {
379 return 0;
380}
Daniel Dunbarf3cad362009-03-25 04:13:45 +0000381
382DerivedArgList *Generic_GCC::TranslateArgs(InputArgList &Args) const {
383 return new DerivedArgList(Args, true);
384}
Daniel Dunbar75358d22009-03-30 21:06:03 +0000385
Daniel Dunbarf7b8eec2009-06-29 20:52:51 +0000386/// OpenBSD - OpenBSD tool chain which can call as(1) and ld(1) directly.
387
388OpenBSD::OpenBSD(const HostInfo &Host, const llvm::Triple& Triple)
389 : Generic_GCC(Host, Triple) {
390 getFilePaths().push_back(getHost().getDriver().Dir + "/../lib");
391 getFilePaths().push_back("/usr/lib");
392}
393
394Tool &OpenBSD::SelectTool(const Compilation &C, const JobAction &JA) const {
395 Action::ActionClass Key;
396 if (getHost().getDriver().ShouldUseClangCompiler(C, JA, getArchName()))
397 Key = Action::AnalyzeJobClass;
398 else
399 Key = JA.getKind();
400
401 Tool *&T = Tools[Key];
402 if (!T) {
403 switch (Key) {
404 case Action::AssembleJobClass:
405 T = new tools::openbsd::Assemble(*this); break;
406 case Action::LinkJobClass:
407 T = new tools::openbsd::Link(*this); break;
408 default:
409 T = &Generic_GCC::SelectTool(C, JA);
410 }
411 }
412
413 return *T;
414}
415
Daniel Dunbar75358d22009-03-30 21:06:03 +0000416/// FreeBSD - FreeBSD tool chain which can call as(1) and ld(1) directly.
417
Daniel Dunbarcb8ab232009-05-22 02:53:45 +0000418FreeBSD::FreeBSD(const HostInfo &Host, const llvm::Triple& Triple, bool Lib32)
419 : Generic_GCC(Host, Triple) {
Daniel Dunbarbc534662009-04-02 18:30:04 +0000420 if (Lib32) {
Daniel Dunbar75358d22009-03-30 21:06:03 +0000421 getFilePaths().push_back(getHost().getDriver().Dir + "/../lib32");
Daniel Dunbarbc534662009-04-02 18:30:04 +0000422 getFilePaths().push_back("/usr/lib32");
423 } else {
Daniel Dunbar75358d22009-03-30 21:06:03 +0000424 getFilePaths().push_back(getHost().getDriver().Dir + "/../lib");
Daniel Dunbarbc534662009-04-02 18:30:04 +0000425 getFilePaths().push_back("/usr/lib");
426 }
Daniel Dunbar75358d22009-03-30 21:06:03 +0000427}
428
429Tool &FreeBSD::SelectTool(const Compilation &C, const JobAction &JA) const {
430 Action::ActionClass Key;
431 if (getHost().getDriver().ShouldUseClangCompiler(C, JA, getArchName()))
432 Key = Action::AnalyzeJobClass;
433 else
434 Key = JA.getKind();
435
436 Tool *&T = Tools[Key];
437 if (!T) {
438 switch (Key) {
Daniel Dunbar68a31d42009-03-31 17:45:15 +0000439 case Action::AssembleJobClass:
440 T = new tools::freebsd::Assemble(*this); break;
Daniel Dunbar008f54a2009-04-01 19:36:32 +0000441 case Action::LinkJobClass:
442 T = new tools::freebsd::Link(*this); break;
Daniel Dunbar75358d22009-03-30 21:06:03 +0000443 default:
444 T = &Generic_GCC::SelectTool(C, JA);
445 }
446 }
447
448 return *T;
449}
Daniel Dunbar11e1b402009-05-02 18:28:39 +0000450
Edward O'Callaghane7925a02009-08-22 01:06:46 +0000451/// AuroraUX - AuroraUX tool chain which can call as(1) and ld(1) directly.
452
453AuroraUX::AuroraUX(const HostInfo &Host, const llvm::Triple& Triple)
454 : Generic_GCC(Host, Triple) {
455
456 // Path mangling to find libexec
457 std::string Path(getHost().getDriver().Dir);
458
459 Path += "/../libexec";
460 getProgramPaths().push_back(Path);
461 getProgramPaths().push_back(getHost().getDriver().Dir);
462
463 getFilePaths().push_back(getHost().getDriver().Dir + "/../lib");
464 getFilePaths().push_back("/usr/lib");
465 getFilePaths().push_back("/usr/sfw/lib");
466 getFilePaths().push_back("/opt/gcc4/lib");
467
468}
469
470Tool &AuroraUX::SelectTool(const Compilation &C, const JobAction &JA) const {
471 Action::ActionClass Key;
472 if (getHost().getDriver().ShouldUseClangCompiler(C, JA, getArchName()))
473 Key = Action::AnalyzeJobClass;
474 else
475 Key = JA.getKind();
476
477 Tool *&T = Tools[Key];
478 if (!T) {
479 switch (Key) {
480 case Action::AssembleJobClass:
481 T = new tools::auroraux::Assemble(*this); break;
482 case Action::LinkJobClass:
483 T = new tools::auroraux::Link(*this); break;
484 default:
485 T = &Generic_GCC::SelectTool(C, JA);
486 }
487 }
488
489 return *T;
490}
491
492
Eli Friedman6b3454a2009-05-26 07:52:18 +0000493/// Linux toolchain (very bare-bones at the moment).
494
495Linux::Linux(const HostInfo &Host, const llvm::Triple& Triple)
496 : Generic_GCC(Host, Triple) {
497 getFilePaths().push_back(getHost().getDriver().Dir + "/../lib/clang/1.0/");
498 getFilePaths().push_back("/lib/");
499 getFilePaths().push_back("/usr/lib/");
Daniel Dunbara9822de2009-08-06 01:47:11 +0000500
501 // Depending on the Linux distribution, any combination of lib{,32,64} is
502 // possible. E.g. Debian uses lib and lib32 for mixed i386/x86-64 systems,
503 // openSUSE uses lib and lib64 for the same purpose.
504 getFilePaths().push_back("/lib32/");
505 getFilePaths().push_back("/usr/lib32/");
506 getFilePaths().push_back("/lib64/");
507 getFilePaths().push_back("/usr/lib64/");
508
Eli Friedman6b3454a2009-05-26 07:52:18 +0000509 // FIXME: Figure out some way to get gcc's libdir
510 // (e.g. /usr/lib/gcc/i486-linux-gnu/4.3/ for Ubuntu 32-bit); we need
511 // crtbegin.o/crtend.o/etc., and want static versions of various
512 // libraries. If we had our own crtbegin.o/crtend.o/etc, we could probably
513 // get away with using shared versions in /usr/lib, though.
514 // We could fall back to the approach we used for includes (a massive
515 // list), but that's messy at best.
516}
517
Daniel Dunbar11e1b402009-05-02 18:28:39 +0000518/// DragonFly - DragonFly tool chain which can call as(1) and ld(1) directly.
519
Daniel Dunbarcb8ab232009-05-22 02:53:45 +0000520DragonFly::DragonFly(const HostInfo &Host, const llvm::Triple& Triple)
521 : Generic_GCC(Host, Triple) {
Daniel Dunbar11e1b402009-05-02 18:28:39 +0000522
523 // Path mangling to find libexec
524 std::string Path(getHost().getDriver().Dir);
525
526 Path += "/../libexec";
527 getProgramPaths().push_back(Path);
528 getProgramPaths().push_back(getHost().getDriver().Dir);
529
530 getFilePaths().push_back(getHost().getDriver().Dir + "/../lib");
531 getFilePaths().push_back("/usr/lib");
532 getFilePaths().push_back("/usr/lib/gcc41");
533}
534
535Tool &DragonFly::SelectTool(const Compilation &C, const JobAction &JA) const {
536 Action::ActionClass Key;
537 if (getHost().getDriver().ShouldUseClangCompiler(C, JA, getArchName()))
538 Key = Action::AnalyzeJobClass;
539 else
540 Key = JA.getKind();
541
542 Tool *&T = Tools[Key];
543 if (!T) {
544 switch (Key) {
545 case Action::AssembleJobClass:
546 T = new tools::dragonfly::Assemble(*this); break;
547 case Action::LinkJobClass:
548 T = new tools::dragonfly::Link(*this); break;
549 default:
550 T = &Generic_GCC::SelectTool(C, JA);
551 }
552 }
553
554 return *T;
555}