blob: eb304958c2d03fab2782a6bfb7788894896a3e9e [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 Dunbar8eddb3f2009-03-20 00:57:52 +000028/// Darwin_X86 - Darwin tool chain for i386 and x86_64.
29
Daniel Dunbarcb8ab232009-05-22 02:53:45 +000030Darwin_X86::Darwin_X86(const HostInfo &Host, const llvm::Triple& Triple,
Daniel Dunbarc50b00d2009-03-23 16:15:50 +000031 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 Dunbar8eddb3f2009-03-20 00:57:52 +000092Darwin_X86::~Darwin_X86() {
93 // 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
99Tool &Darwin_X86::SelectTool(const Compilation &C,
100 const JobAction &JA) const {
101 Action::ActionClass Key;
Daniel Dunbaraf80e1f2009-03-24 18:57:02 +0000102 if (getHost().getDriver().ShouldUseClangCompiler(C, JA, getArchName()))
Daniel Dunbar8eddb3f2009-03-20 00:57:52 +0000103 Key = Action::AnalyzeJobClass;
104 else
105 Key = JA.getKind();
106
107 Tool *&T = Tools[Key];
108 if (!T) {
109 switch (Key) {
110 case Action::InputClass:
111 case Action::BindArchClass:
112 assert(0 && "Invalid tool kind.");
113 case Action::PreprocessJobClass:
Daniel Dunbar9120f172009-03-29 22:27:40 +0000114 T = new tools::darwin::Preprocess(*this); break;
Daniel Dunbar8eddb3f2009-03-20 00:57:52 +0000115 case Action::AnalyzeJobClass:
116 T = new tools::Clang(*this); break;
Daniel Dunbar9120f172009-03-29 22:27:40 +0000117 case Action::PrecompileJobClass:
Daniel Dunbar8eddb3f2009-03-20 00:57:52 +0000118 case Action::CompileJobClass:
Daniel Dunbar9120f172009-03-29 22:27:40 +0000119 T = new tools::darwin::Compile(*this); break;
Daniel Dunbar8eddb3f2009-03-20 00:57:52 +0000120 case Action::AssembleJobClass:
Daniel Dunbar8cac5f72009-03-20 16:06:39 +0000121 T = new tools::darwin::Assemble(*this); break;
Daniel Dunbar8eddb3f2009-03-20 00:57:52 +0000122 case Action::LinkJobClass:
Daniel Dunbar02633b52009-03-26 16:23:12 +0000123 T = new tools::darwin::Link(*this, MacosxVersionMin.c_str()); break;
Daniel Dunbar8eddb3f2009-03-20 00:57:52 +0000124 case Action::LipoJobClass:
125 T = new tools::darwin::Lipo(*this); break;
126 }
127 }
128
129 return *T;
130}
131
Daniel Dunbarf3cad362009-03-25 04:13:45 +0000132DerivedArgList *Darwin_X86::TranslateArgs(InputArgList &Args) const {
Daniel Dunbar4e7e9cf2009-03-25 06:12:34 +0000133 DerivedArgList *DAL = new DerivedArgList(Args, false);
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000134 const OptTable &Opts = getHost().getDriver().getOpts();
135
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.
142
Daniel Dunbarff8857a2009-04-10 20:11:50 +0000143 Arg *OSXVersion =
144 Args.getLastArg(options::OPT_mmacosx_version_min_EQ, false);
145 Arg *iPhoneVersion =
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.
153 //
154 // FIXME: This will need to be fixed when we merge in arm support.
Daniel Dunbarf36a06a2009-04-10 21:00:07 +0000155
156 // Look for MACOSX_DEPLOYMENT_TARGET, otherwise use the version
157 // from the host.
158 const char *Version = ::getenv("MACOSX_DEPLOYMENT_TARGET");
159 if (!Version)
160 Version = MacosxVersionMin.c_str();
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000161 const Option *O = Opts.getOption(options::OPT_mmacosx_version_min_EQ);
Daniel Dunbarf36a06a2009-04-10 21:00:07 +0000162 DAL->append(DAL->MakeJoinedArg(0, O, Version));
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000163 }
Daniel Dunbar4e7e9cf2009-03-25 06:12:34 +0000164
165 for (ArgList::iterator it = Args.begin(), ie = Args.end(); it != ie; ++it) {
166 Arg *A = *it;
167
168 if (A->getOption().matches(options::OPT_Xarch__)) {
169 // FIXME: Canonicalize name.
170 if (getArchName() != A->getValue(Args, 0))
171 continue;
172
173 // FIXME: The arg is leaked here, and we should have a nicer
174 // interface for this.
Daniel Dunbar4e7e9cf2009-03-25 06:12:34 +0000175 unsigned Prev, Index = Prev = A->getIndex() + 1;
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000176 Arg *XarchArg = Opts.ParseOneArg(Args, Index);
Daniel Dunbar4e7e9cf2009-03-25 06:12:34 +0000177
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.
181 //
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()) {
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000188 getHost().getDriver().Diag(clang::diag::err_drv_invalid_Xarch_argument)
Daniel Dunbar4e7e9cf2009-03-25 06:12:34 +0000189 << A->getAsString(Args);
190 continue;
191 }
192
Daniel Dunbar478edc22009-03-29 22:29:05 +0000193 XarchArg->setBaseArg(A);
Daniel Dunbar4e7e9cf2009-03-25 06:12:34 +0000194 A = XarchArg;
195 }
196
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000197 // 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();
201 switch (id) {
202 default:
203 DAL->append(A);
204 break;
205
206 case options::OPT_mkernel:
207 case options::OPT_fapple_kext:
208 DAL->append(A);
Daniel Dunbar478edc22009-03-29 22:29:05 +0000209 DAL->append(DAL->MakeFlagArg(A, Opts.getOption(options::OPT_static)));
210 DAL->append(DAL->MakeFlagArg(A, Opts.getOption(options::OPT_static)));
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000211 break;
212
213 case options::OPT_dependency_file:
Daniel Dunbar478edc22009-03-29 22:29:05 +0000214 DAL->append(DAL->MakeSeparateArg(A, Opts.getOption(options::OPT_MF),
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000215 A->getValue(Args)));
216 break;
217
218 case options::OPT_gfull:
Daniel Dunbar478edc22009-03-29 22:29:05 +0000219 DAL->append(DAL->MakeFlagArg(A, Opts.getOption(options::OPT_g_Flag)));
220 DAL->append(DAL->MakeFlagArg(A,
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000221 Opts.getOption(options::OPT_fno_eliminate_unused_debug_symbols)));
222 break;
223
224 case options::OPT_gused:
Daniel Dunbar478edc22009-03-29 22:29:05 +0000225 DAL->append(DAL->MakeFlagArg(A, Opts.getOption(options::OPT_g_Flag)));
226 DAL->append(DAL->MakeFlagArg(A,
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000227 Opts.getOption(options::OPT_feliminate_unused_debug_symbols)));
228 break;
229
230 case options::OPT_fterminated_vtables:
231 case options::OPT_findirect_virtual_calls:
Daniel Dunbar478edc22009-03-29 22:29:05 +0000232 DAL->append(DAL->MakeFlagArg(A,
233 Opts.getOption(options::OPT_fapple_kext)));
234 DAL->append(DAL->MakeFlagArg(A, Opts.getOption(options::OPT_static)));
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000235 break;
236
237 case options::OPT_shared:
Daniel Dunbar478edc22009-03-29 22:29:05 +0000238 DAL->append(DAL->MakeFlagArg(A, Opts.getOption(options::OPT_dynamiclib)));
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000239 break;
240
241 case options::OPT_fconstant_cfstrings:
Daniel Dunbar478edc22009-03-29 22:29:05 +0000242 DAL->append(DAL->MakeFlagArg(A,
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000243 Opts.getOption(options::OPT_mconstant_cfstrings)));
244 break;
245
246 case options::OPT_fno_constant_cfstrings:
Daniel Dunbar478edc22009-03-29 22:29:05 +0000247 DAL->append(DAL->MakeFlagArg(A,
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000248 Opts.getOption(options::OPT_mno_constant_cfstrings)));
249 break;
250
251 case options::OPT_Wnonportable_cfstrings:
Daniel Dunbar478edc22009-03-29 22:29:05 +0000252 DAL->append(DAL->MakeFlagArg(A,
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000253 Opts.getOption(options::OPT_mwarn_nonportable_cfstrings)));
254 break;
255
256 case options::OPT_Wno_nonportable_cfstrings:
Daniel Dunbar478edc22009-03-29 22:29:05 +0000257 DAL->append(DAL->MakeFlagArg(A,
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000258 Opts.getOption(options::OPT_mno_warn_nonportable_cfstrings)));
259 break;
260
261 case options::OPT_fpascal_strings:
Daniel Dunbar478edc22009-03-29 22:29:05 +0000262 DAL->append(DAL->MakeFlagArg(A,
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000263 Opts.getOption(options::OPT_mpascal_strings)));
264 break;
265
266 case options::OPT_fno_pascal_strings:
Daniel Dunbar478edc22009-03-29 22:29:05 +0000267 DAL->append(DAL->MakeFlagArg(A,
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000268 Opts.getOption(options::OPT_mno_pascal_strings)));
269 break;
270 }
Daniel Dunbar4e7e9cf2009-03-25 06:12:34 +0000271 }
272
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000273 // FIXME: Actually, gcc always adds this, but it is filtered for
274 // duplicates somewhere. This also changes the order of things, so
275 // look it up.
276 if (getArchName() == "x86_64")
277 if (!Args.hasArg(options::OPT_m64, false))
Daniel Dunbar478edc22009-03-29 22:29:05 +0000278 DAL->append(DAL->MakeFlagArg(0, Opts.getOption(options::OPT_m64)));
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000279
280 if (!Args.hasArg(options::OPT_mtune_EQ, false))
Daniel Dunbar478edc22009-03-29 22:29:05 +0000281 DAL->append(DAL->MakeJoinedArg(0, Opts.getOption(options::OPT_mtune_EQ),
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000282 "core2"));
283
Daniel Dunbar4e7e9cf2009-03-25 06:12:34 +0000284 return DAL;
Daniel Dunbar8eddb3f2009-03-20 00:57:52 +0000285}
286
287bool Darwin_X86::IsMathErrnoDefault() const {
288 return false;
289}
290
291bool 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";
295}
296
297const char *Darwin_X86::GetDefaultRelocationModel() const {
298 return "pic";
299}
300
301const char *Darwin_X86::GetForcedPicModel() const {
302 if (getArchName() == "x86_64")
303 return "pic";
304 return 0;
305}
306
Daniel Dunbar39176082009-03-20 00:20:03 +0000307/// 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.
310
Daniel Dunbarcb8ab232009-05-22 02:53:45 +0000311Generic_GCC::Generic_GCC(const HostInfo &Host, const llvm::Triple& Triple)
312 : ToolChain(Host, Triple)
Daniel Dunbarc50b00d2009-03-23 16:15:50 +0000313{
Daniel Dunbar82fa7c52009-03-24 04:07:10 +0000314 std::string Path(getHost().getDriver().Dir);
315 Path += "/../libexec";
316 getProgramPaths().push_back(Path);
317
Daniel Dunbarc50b00d2009-03-23 16:15:50 +0000318 getProgramPaths().push_back(getHost().getDriver().Dir);
319}
320
Daniel Dunbar39176082009-03-20 00:20:03 +0000321Generic_GCC::~Generic_GCC() {
322 // Free tool implementations.
323 for (llvm::DenseMap<unsigned, Tool*>::iterator
324 it = Tools.begin(), ie = Tools.end(); it != ie; ++it)
325 delete it->second;
326}
327
328Tool &Generic_GCC::SelectTool(const Compilation &C,
329 const JobAction &JA) const {
330 Action::ActionClass Key;
Daniel Dunbaraf80e1f2009-03-24 18:57:02 +0000331 if (getHost().getDriver().ShouldUseClangCompiler(C, JA, getArchName()))
Daniel Dunbar39176082009-03-20 00:20:03 +0000332 Key = Action::AnalyzeJobClass;
333 else
334 Key = JA.getKind();
335
336 Tool *&T = Tools[Key];
337 if (!T) {
338 switch (Key) {
Daniel Dunbar8eddb3f2009-03-20 00:57:52 +0000339 case Action::InputClass:
340 case Action::BindArchClass:
Daniel Dunbar39176082009-03-20 00:20:03 +0000341 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;
Daniel Dunbar8eddb3f2009-03-20 00:57:52 +0000354
355 // This is a bit ungeneric, but the only platform using a driver
356 // driver is Darwin.
357 case Action::LipoJobClass:
358 T = new tools::darwin::Lipo(*this); break;
Daniel Dunbar39176082009-03-20 00:20:03 +0000359 }
360 }
361
362 return *T;
363}
364
365bool Generic_GCC::IsMathErrnoDefault() const {
366 return true;
367}
368
369bool Generic_GCC::IsUnwindTablesDefault() const {
Daniel Dunbar8eddb3f2009-03-20 00:57:52 +0000370 // FIXME: Gross; we should probably have some separate target
371 // definition, possibly even reusing the one in clang.
Daniel Dunbar39176082009-03-20 00:20:03 +0000372 return getArchName() == "x86_64";
373}
374
375const char *Generic_GCC::GetDefaultRelocationModel() const {
376 return "static";
377}
378
379const char *Generic_GCC::GetForcedPicModel() const {
380 return 0;
381}
Daniel Dunbarf3cad362009-03-25 04:13:45 +0000382
383DerivedArgList *Generic_GCC::TranslateArgs(InputArgList &Args) const {
384 return new DerivedArgList(Args, true);
385}
Daniel Dunbar75358d22009-03-30 21:06:03 +0000386
Daniel Dunbarf7b8eec2009-06-29 20:52:51 +0000387/// OpenBSD - OpenBSD tool chain which can call as(1) and ld(1) directly.
388
389OpenBSD::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");
393}
394
395Tool &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;
399 else
400 Key = JA.getKind();
401
402 Tool *&T = Tools[Key];
403 if (!T) {
404 switch (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;
409 default:
410 T = &Generic_GCC::SelectTool(C, JA);
411 }
412 }
413
414 return *T;
415}
416
Daniel Dunbar75358d22009-03-30 21:06:03 +0000417/// FreeBSD - FreeBSD tool chain which can call as(1) and ld(1) directly.
418
Daniel Dunbarcb8ab232009-05-22 02:53:45 +0000419FreeBSD::FreeBSD(const HostInfo &Host, const llvm::Triple& Triple, bool Lib32)
420 : Generic_GCC(Host, Triple) {
Daniel Dunbarbc534662009-04-02 18:30:04 +0000421 if (Lib32) {
Daniel Dunbar75358d22009-03-30 21:06:03 +0000422 getFilePaths().push_back(getHost().getDriver().Dir + "/../lib32");
Daniel Dunbarbc534662009-04-02 18:30:04 +0000423 getFilePaths().push_back("/usr/lib32");
424 } else {
Daniel Dunbar75358d22009-03-30 21:06:03 +0000425 getFilePaths().push_back(getHost().getDriver().Dir + "/../lib");
Daniel Dunbarbc534662009-04-02 18:30:04 +0000426 getFilePaths().push_back("/usr/lib");
427 }
Daniel Dunbar75358d22009-03-30 21:06:03 +0000428}
429
430Tool &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;
434 else
435 Key = JA.getKind();
436
437 Tool *&T = Tools[Key];
438 if (!T) {
439 switch (Key) {
Daniel Dunbar68a31d42009-03-31 17:45:15 +0000440 case Action::AssembleJobClass:
441 T = new tools::freebsd::Assemble(*this); break;
Daniel Dunbar008f54a2009-04-01 19:36:32 +0000442 case Action::LinkJobClass:
443 T = new tools::freebsd::Link(*this); break;
Daniel Dunbar75358d22009-03-30 21:06:03 +0000444 default:
445 T = &Generic_GCC::SelectTool(C, JA);
446 }
447 }
448
449 return *T;
450}
Daniel Dunbar11e1b402009-05-02 18:28:39 +0000451
Eli Friedman6b3454a2009-05-26 07:52:18 +0000452/// Linux toolchain (very bare-bones at the moment).
453
454Linux::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/");
Daniel Dunbara9822de2009-08-06 01:47:11 +0000459
460 // Depending on the Linux distribution, any combination of lib{,32,64} is
461 // possible. E.g. Debian uses lib and lib32 for mixed i386/x86-64 systems,
462 // openSUSE uses lib and lib64 for the same purpose.
463 getFilePaths().push_back("/lib32/");
464 getFilePaths().push_back("/usr/lib32/");
465 getFilePaths().push_back("/lib64/");
466 getFilePaths().push_back("/usr/lib64/");
467
Eli Friedman6b3454a2009-05-26 07:52:18 +0000468 // FIXME: Figure out some way to get gcc's libdir
469 // (e.g. /usr/lib/gcc/i486-linux-gnu/4.3/ for Ubuntu 32-bit); we need
470 // crtbegin.o/crtend.o/etc., and want static versions of various
471 // libraries. If we had our own crtbegin.o/crtend.o/etc, we could probably
472 // get away with using shared versions in /usr/lib, though.
473 // We could fall back to the approach we used for includes (a massive
474 // list), but that's messy at best.
475}
476
Daniel Dunbar11e1b402009-05-02 18:28:39 +0000477/// DragonFly - DragonFly tool chain which can call as(1) and ld(1) directly.
478
Daniel Dunbarcb8ab232009-05-22 02:53:45 +0000479DragonFly::DragonFly(const HostInfo &Host, const llvm::Triple& Triple)
480 : Generic_GCC(Host, Triple) {
Daniel Dunbar11e1b402009-05-02 18:28:39 +0000481
482 // Path mangling to find libexec
483 std::string Path(getHost().getDriver().Dir);
484
485 Path += "/../libexec";
486 getProgramPaths().push_back(Path);
487 getProgramPaths().push_back(getHost().getDriver().Dir);
488
489 getFilePaths().push_back(getHost().getDriver().Dir + "/../lib");
490 getFilePaths().push_back("/usr/lib");
491 getFilePaths().push_back("/usr/lib/gcc41");
492}
493
494Tool &DragonFly::SelectTool(const Compilation &C, const JobAction &JA) const {
495 Action::ActionClass Key;
496 if (getHost().getDriver().ShouldUseClangCompiler(C, JA, getArchName()))
497 Key = Action::AnalyzeJobClass;
498 else
499 Key = JA.getKind();
500
501 Tool *&T = Tools[Key];
502 if (!T) {
503 switch (Key) {
504 case Action::AssembleJobClass:
505 T = new tools::dragonfly::Assemble(*this); break;
506 case Action::LinkJobClass:
507 T = new tools::dragonfly::Link(*this); break;
508 default:
509 T = &Generic_GCC::SelectTool(C, JA);
510 }
511 }
512
513 return *T;
514}