ToolChains.cpp revision f395528158379e7ea9f6ff4bbb791abadca15aab
1//===--- 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
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"
18
19#include "llvm/ADT/StringExtras.h"
20#include "llvm/Support/raw_ostream.h"
21#include "llvm/System/Path.h"
22
23#include <cstdlib> // ::getenv
24
25using namespace clang::driver;
26using namespace clang::driver::toolchains;
27
28/// Darwin - Darwin tool chain for i386 and x86_64.
29
30Darwin::Darwin(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];
40
41  llvm::raw_string_ostream(MacosxVersionMin)
42    << "10." << DarwinVersion[0] - 4 << '.' << DarwinVersion[1];
43
44  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
85  Path = getHost().getDriver().Dir;
86  Path += "/../libexec";
87  getProgramPaths().push_back(Path);
88
89  getProgramPaths().push_back(getHost().getDriver().Dir);
90}
91
92Darwin::~Darwin() {
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::SelectTool(const Compilation &C, const JobAction &JA) const {
100  Action::ActionClass Key;
101  if (getHost().getDriver().ShouldUseClangCompiler(C, JA, getArchName()))
102    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:
113      T = new tools::darwin::Preprocess(*this); break;
114    case Action::AnalyzeJobClass:
115      T = new tools::Clang(*this); break;
116    case Action::PrecompileJobClass:
117    case Action::CompileJobClass:
118      T = new tools::darwin::Compile(*this); break;
119    case Action::AssembleJobClass:
120      T = new tools::darwin::Assemble(*this); break;
121    case Action::LinkJobClass:
122      T = new tools::darwin::Link(*this); break;
123    case Action::LipoJobClass:
124      T = new tools::darwin::Lipo(*this); break;
125    }
126  }
127
128  return *T;
129}
130
131DerivedArgList *Darwin::TranslateArgs(InputArgList &Args) const {
132  DerivedArgList *DAL = new DerivedArgList(Args, false);
133  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
142  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.
154
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();
160    const Option *O = Opts.getOption(options::OPT_mmacosx_version_min_EQ);
161    DAL->append(DAL->MakeJoinedArg(0, O, Version));
162  }
163
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.
174      unsigned Prev, Index = Prev = A->getIndex() + 1;
175      Arg *XarchArg = Opts.ParseOneArg(Args, Index);
176
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()) {
187       getHost().getDriver().Diag(clang::diag::err_drv_invalid_Xarch_argument)
188          << A->getAsString(Args);
189        continue;
190      }
191
192      XarchArg->setBaseArg(A);
193      A = XarchArg;
194    }
195
196    // 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);
208      DAL->append(DAL->MakeFlagArg(A, Opts.getOption(options::OPT_static)));
209      DAL->append(DAL->MakeFlagArg(A, Opts.getOption(options::OPT_static)));
210      break;
211
212    case options::OPT_dependency_file:
213      DAL->append(DAL->MakeSeparateArg(A, Opts.getOption(options::OPT_MF),
214                                       A->getValue(Args)));
215      break;
216
217    case options::OPT_gfull:
218      DAL->append(DAL->MakeFlagArg(A, Opts.getOption(options::OPT_g_Flag)));
219      DAL->append(DAL->MakeFlagArg(A,
220             Opts.getOption(options::OPT_fno_eliminate_unused_debug_symbols)));
221      break;
222
223    case options::OPT_gused:
224      DAL->append(DAL->MakeFlagArg(A, Opts.getOption(options::OPT_g_Flag)));
225      DAL->append(DAL->MakeFlagArg(A,
226             Opts.getOption(options::OPT_feliminate_unused_debug_symbols)));
227      break;
228
229    case options::OPT_fterminated_vtables:
230    case options::OPT_findirect_virtual_calls:
231      DAL->append(DAL->MakeFlagArg(A,
232                                   Opts.getOption(options::OPT_fapple_kext)));
233      DAL->append(DAL->MakeFlagArg(A, Opts.getOption(options::OPT_static)));
234      break;
235
236    case options::OPT_shared:
237      DAL->append(DAL->MakeFlagArg(A, Opts.getOption(options::OPT_dynamiclib)));
238      break;
239
240    case options::OPT_fconstant_cfstrings:
241      DAL->append(DAL->MakeFlagArg(A,
242                             Opts.getOption(options::OPT_mconstant_cfstrings)));
243      break;
244
245    case options::OPT_fno_constant_cfstrings:
246      DAL->append(DAL->MakeFlagArg(A,
247                          Opts.getOption(options::OPT_mno_constant_cfstrings)));
248      break;
249
250    case options::OPT_Wnonportable_cfstrings:
251      DAL->append(DAL->MakeFlagArg(A,
252                     Opts.getOption(options::OPT_mwarn_nonportable_cfstrings)));
253      break;
254
255    case options::OPT_Wno_nonportable_cfstrings:
256      DAL->append(DAL->MakeFlagArg(A,
257                  Opts.getOption(options::OPT_mno_warn_nonportable_cfstrings)));
258      break;
259
260    case options::OPT_fpascal_strings:
261      DAL->append(DAL->MakeFlagArg(A,
262                                 Opts.getOption(options::OPT_mpascal_strings)));
263      break;
264
265    case options::OPT_fno_pascal_strings:
266      DAL->append(DAL->MakeFlagArg(A,
267                              Opts.getOption(options::OPT_mno_pascal_strings)));
268      break;
269    }
270  }
271
272  // 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))
277      DAL->append(DAL->MakeFlagArg(0, Opts.getOption(options::OPT_m64)));
278
279  if (!Args.hasArg(options::OPT_mtune_EQ, false))
280    DAL->append(DAL->MakeJoinedArg(0, Opts.getOption(options::OPT_mtune_EQ),
281                                    "core2"));
282
283  return DAL;
284}
285
286bool Darwin::IsMathErrnoDefault() const {
287  return false;
288}
289
290bool Darwin::IsUnwindTablesDefault() const {
291  // 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
296const char *Darwin::GetDefaultRelocationModel() const {
297  return "pic";
298}
299
300const char *Darwin::GetForcedPicModel() const {
301  if (getArchName() == "x86_64")
302    return "pic";
303  return 0;
304}
305
306/// 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
310Generic_GCC::Generic_GCC(const HostInfo &Host, const llvm::Triple& Triple)
311  : ToolChain(Host, Triple)
312{
313  std::string Path(getHost().getDriver().Dir);
314  Path += "/../libexec";
315  getProgramPaths().push_back(Path);
316
317  getProgramPaths().push_back(getHost().getDriver().Dir);
318}
319
320Generic_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;
330  if (getHost().getDriver().ShouldUseClangCompiler(C, JA, getArchName()))
331    Key = Action::AnalyzeJobClass;
332  else
333    Key = JA.getKind();
334
335  Tool *&T = Tools[Key];
336  if (!T) {
337    switch (Key) {
338    case Action::InputClass:
339    case Action::BindArchClass:
340      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;
353
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;
358    }
359  }
360
361  return *T;
362}
363
364bool Generic_GCC::IsMathErrnoDefault() const {
365  return true;
366}
367
368bool Generic_GCC::IsUnwindTablesDefault() const {
369  // FIXME: Gross; we should probably have some separate target
370  // definition, possibly even reusing the one in clang.
371  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}
381
382DerivedArgList *Generic_GCC::TranslateArgs(InputArgList &Args) const {
383  return new DerivedArgList(Args, true);
384}
385
386/// 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
416/// FreeBSD - FreeBSD tool chain which can call as(1) and ld(1) directly.
417
418FreeBSD::FreeBSD(const HostInfo &Host, const llvm::Triple& Triple, bool Lib32)
419  : Generic_GCC(Host, Triple) {
420  if (Lib32) {
421    getFilePaths().push_back(getHost().getDriver().Dir + "/../lib32");
422    getFilePaths().push_back("/usr/lib32");
423  } else {
424    getFilePaths().push_back(getHost().getDriver().Dir + "/../lib");
425    getFilePaths().push_back("/usr/lib");
426  }
427}
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) {
439    case Action::AssembleJobClass:
440      T = new tools::freebsd::Assemble(*this); break;
441    case Action::LinkJobClass:
442      T = new tools::freebsd::Link(*this); break;
443    default:
444      T = &Generic_GCC::SelectTool(C, JA);
445    }
446  }
447
448  return *T;
449}
450
451/// 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
493/// 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/");
500
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
509  // 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
518/// DragonFly - DragonFly tool chain which can call as(1) and ld(1) directly.
519
520DragonFly::DragonFly(const HostInfo &Host, const llvm::Triple& Triple)
521  : Generic_GCC(Host, Triple) {
522
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}
556