ToolChains.cpp revision a6046bec7fc835186dde134fb81aa1b7d45cd9f0
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 bool _IsIPhone) 34 : ToolChain(Host, Triple) { 35 DarwinVersion[0] = _DarwinVersion[0]; 36 DarwinVersion[1] = _DarwinVersion[1]; 37 DarwinVersion[2] = _DarwinVersion[2]; 38 GCCVersion[0] = _GCCVersion[0]; 39 GCCVersion[1] = _GCCVersion[1]; 40 GCCVersion[2] = _GCCVersion[2]; 41 IsIPhone = _IsIPhone; 42 43 llvm::raw_string_ostream(MacosxVersionMin) 44 << "10." << DarwinVersion[0] - 4 << '.' << DarwinVersion[1]; 45 46 // FIXME: Lift default up. 47 IPhoneOSVersionMin = "3.0"; 48 49 ToolChainDir = "i686-apple-darwin"; 50 ToolChainDir += llvm::utostr(DarwinVersion[0]); 51 ToolChainDir += "/"; 52 ToolChainDir += llvm::utostr(GCCVersion[0]); 53 ToolChainDir += '.'; 54 ToolChainDir += llvm::utostr(GCCVersion[1]); 55 ToolChainDir += '.'; 56 ToolChainDir += llvm::utostr(GCCVersion[2]); 57 58 std::string Path; 59 if (getArchName() == "x86_64") { 60 Path = getHost().getDriver().Dir; 61 Path += "/../lib/gcc/"; 62 Path += getToolChainDir(); 63 Path += "/x86_64"; 64 getFilePaths().push_back(Path); 65 66 Path = "/usr/lib/gcc/"; 67 Path += getToolChainDir(); 68 Path += "/x86_64"; 69 getFilePaths().push_back(Path); 70 } 71 72 Path = getHost().getDriver().Dir; 73 Path += "/../lib/gcc/"; 74 Path += getToolChainDir(); 75 getFilePaths().push_back(Path); 76 77 Path = "/usr/lib/gcc/"; 78 Path += getToolChainDir(); 79 getFilePaths().push_back(Path); 80 81 Path = getHost().getDriver().Dir; 82 Path += "/../libexec/gcc/"; 83 Path += getToolChainDir(); 84 getProgramPaths().push_back(Path); 85 86 Path = "/usr/libexec/gcc/"; 87 Path += getToolChainDir(); 88 getProgramPaths().push_back(Path); 89 90 Path = getHost().getDriver().Dir; 91 Path += "/../libexec"; 92 getProgramPaths().push_back(Path); 93 94 getProgramPaths().push_back(getHost().getDriver().Dir); 95} 96 97Darwin::~Darwin() { 98 // Free tool implementations. 99 for (llvm::DenseMap<unsigned, Tool*>::iterator 100 it = Tools.begin(), ie = Tools.end(); it != ie; ++it) 101 delete it->second; 102} 103 104Tool &Darwin::SelectTool(const Compilation &C, const JobAction &JA) const { 105 Action::ActionClass Key; 106 if (getHost().getDriver().ShouldUseClangCompiler(C, JA, getTriple())) 107 Key = Action::AnalyzeJobClass; 108 else 109 Key = JA.getKind(); 110 111 Tool *&T = Tools[Key]; 112 if (!T) { 113 switch (Key) { 114 case Action::InputClass: 115 case Action::BindArchClass: 116 assert(0 && "Invalid tool kind."); 117 case Action::PreprocessJobClass: 118 T = new tools::darwin::Preprocess(*this); break; 119 case Action::AnalyzeJobClass: 120 T = new tools::Clang(*this); break; 121 case Action::PrecompileJobClass: 122 case Action::CompileJobClass: 123 T = new tools::darwin::Compile(*this); break; 124 case Action::AssembleJobClass: 125 T = new tools::darwin::Assemble(*this); break; 126 case Action::LinkJobClass: 127 T = new tools::darwin::Link(*this); break; 128 case Action::LipoJobClass: 129 T = new tools::darwin::Lipo(*this); break; 130 } 131 } 132 133 return *T; 134} 135 136DerivedArgList *Darwin::TranslateArgs(InputArgList &Args) const { 137 DerivedArgList *DAL = new DerivedArgList(Args, false); 138 const OptTable &Opts = getHost().getDriver().getOpts(); 139 140 // FIXME: We really want to get out of the tool chain level argument 141 // translation business, as it makes the driver functionality much 142 // more opaque. For now, we follow gcc closely solely for the 143 // purpose of easily achieving feature parity & testability. Once we 144 // have something that works, we should reevaluate each translation 145 // and try to push it down into tool specific logic. 146 147 Arg *OSXVersion = 148 Args.getLastArg(options::OPT_mmacosx_version_min_EQ, false); 149 Arg *iPhoneVersion = 150 Args.getLastArg(options::OPT_miphoneos_version_min_EQ, false); 151 if (OSXVersion && iPhoneVersion) { 152 getHost().getDriver().Diag(clang::diag::err_drv_argument_not_allowed_with) 153 << OSXVersion->getAsString(Args) 154 << iPhoneVersion->getAsString(Args); 155 } else if (!OSXVersion && !iPhoneVersion) { 156 // Chose the default version based on the arch. 157 // 158 // FIXME: Are there iPhone overrides for this? 159 160 if (!isIPhone()) { 161 // Look for MACOSX_DEPLOYMENT_TARGET, otherwise use the version 162 // from the host. 163 const char *Version = ::getenv("MACOSX_DEPLOYMENT_TARGET"); 164 if (!Version) 165 Version = MacosxVersionMin.c_str(); 166 const Option *O = Opts.getOption(options::OPT_mmacosx_version_min_EQ); 167 DAL->append(DAL->MakeJoinedArg(0, O, Version)); 168 } else { 169 const char *Version = IPhoneOSVersionMin.c_str(); 170 const Option *O = Opts.getOption(options::OPT_miphoneos_version_min_EQ); 171 DAL->append(DAL->MakeJoinedArg(0, O, Version)); 172 } 173 } 174 175 for (ArgList::iterator it = Args.begin(), ie = Args.end(); it != ie; ++it) { 176 Arg *A = *it; 177 178 if (A->getOption().matches(options::OPT_Xarch__)) { 179 // FIXME: Canonicalize name. 180 if (getArchName() != A->getValue(Args, 0)) 181 continue; 182 183 // FIXME: The arg is leaked here, and we should have a nicer 184 // interface for this. 185 unsigned Prev, Index = Prev = A->getIndex() + 1; 186 Arg *XarchArg = Opts.ParseOneArg(Args, Index); 187 188 // If the argument parsing failed or more than one argument was 189 // consumed, the -Xarch_ argument's parameter tried to consume 190 // extra arguments. Emit an error and ignore. 191 // 192 // We also want to disallow any options which would alter the 193 // driver behavior; that isn't going to work in our model. We 194 // use isDriverOption() as an approximation, although things 195 // like -O4 are going to slip through. 196 if (!XarchArg || Index > Prev + 1 || 197 XarchArg->getOption().isDriverOption()) { 198 getHost().getDriver().Diag(clang::diag::err_drv_invalid_Xarch_argument) 199 << A->getAsString(Args); 200 continue; 201 } 202 203 XarchArg->setBaseArg(A); 204 A = XarchArg; 205 } 206 207 // Sob. These is strictly gcc compatible for the time being. Apple 208 // gcc translates options twice, which means that self-expanding 209 // options add duplicates. 210 options::ID id = A->getOption().getId(); 211 switch (id) { 212 default: 213 DAL->append(A); 214 break; 215 216 case options::OPT_mkernel: 217 case options::OPT_fapple_kext: 218 DAL->append(A); 219 DAL->append(DAL->MakeFlagArg(A, Opts.getOption(options::OPT_static))); 220 DAL->append(DAL->MakeFlagArg(A, Opts.getOption(options::OPT_static))); 221 break; 222 223 case options::OPT_dependency_file: 224 DAL->append(DAL->MakeSeparateArg(A, Opts.getOption(options::OPT_MF), 225 A->getValue(Args))); 226 break; 227 228 case options::OPT_gfull: 229 DAL->append(DAL->MakeFlagArg(A, Opts.getOption(options::OPT_g_Flag))); 230 DAL->append(DAL->MakeFlagArg(A, 231 Opts.getOption(options::OPT_fno_eliminate_unused_debug_symbols))); 232 break; 233 234 case options::OPT_gused: 235 DAL->append(DAL->MakeFlagArg(A, Opts.getOption(options::OPT_g_Flag))); 236 DAL->append(DAL->MakeFlagArg(A, 237 Opts.getOption(options::OPT_feliminate_unused_debug_symbols))); 238 break; 239 240 case options::OPT_fterminated_vtables: 241 case options::OPT_findirect_virtual_calls: 242 DAL->append(DAL->MakeFlagArg(A, 243 Opts.getOption(options::OPT_fapple_kext))); 244 DAL->append(DAL->MakeFlagArg(A, Opts.getOption(options::OPT_static))); 245 break; 246 247 case options::OPT_shared: 248 DAL->append(DAL->MakeFlagArg(A, Opts.getOption(options::OPT_dynamiclib))); 249 break; 250 251 case options::OPT_fconstant_cfstrings: 252 DAL->append(DAL->MakeFlagArg(A, 253 Opts.getOption(options::OPT_mconstant_cfstrings))); 254 break; 255 256 case options::OPT_fno_constant_cfstrings: 257 DAL->append(DAL->MakeFlagArg(A, 258 Opts.getOption(options::OPT_mno_constant_cfstrings))); 259 break; 260 261 case options::OPT_Wnonportable_cfstrings: 262 DAL->append(DAL->MakeFlagArg(A, 263 Opts.getOption(options::OPT_mwarn_nonportable_cfstrings))); 264 break; 265 266 case options::OPT_Wno_nonportable_cfstrings: 267 DAL->append(DAL->MakeFlagArg(A, 268 Opts.getOption(options::OPT_mno_warn_nonportable_cfstrings))); 269 break; 270 271 case options::OPT_fpascal_strings: 272 DAL->append(DAL->MakeFlagArg(A, 273 Opts.getOption(options::OPT_mpascal_strings))); 274 break; 275 276 case options::OPT_fno_pascal_strings: 277 DAL->append(DAL->MakeFlagArg(A, 278 Opts.getOption(options::OPT_mno_pascal_strings))); 279 break; 280 } 281 } 282 283 // FIXME: Actually, gcc always adds this, but it is filtered for 284 // duplicates somewhere. This also changes the order of things, so 285 // look it up. 286 if (getArchName() == "x86_64") 287 if (!Args.hasArg(options::OPT_m64, false)) 288 DAL->append(DAL->MakeFlagArg(0, Opts.getOption(options::OPT_m64))); 289 290 if (!Args.hasArg(options::OPT_mtune_EQ, false)) 291 DAL->append(DAL->MakeJoinedArg(0, Opts.getOption(options::OPT_mtune_EQ), 292 "core2")); 293 294 return DAL; 295} 296 297bool Darwin::IsMathErrnoDefault() const { 298 return false; 299} 300 301bool Darwin::IsUnwindTablesDefault() const { 302 // FIXME: Gross; we should probably have some separate target 303 // definition, possibly even reusing the one in clang. 304 return getArchName() == "x86_64"; 305} 306 307const char *Darwin::GetDefaultRelocationModel() const { 308 return "pic"; 309} 310 311const char *Darwin::GetForcedPicModel() const { 312 if (getArchName() == "x86_64") 313 return "pic"; 314 return 0; 315} 316 317/// Generic_GCC - A tool chain using the 'gcc' command to perform 318/// all subcommands; this relies on gcc translating the majority of 319/// command line options. 320 321Generic_GCC::Generic_GCC(const HostInfo &Host, const llvm::Triple& Triple) 322 : ToolChain(Host, Triple) 323{ 324 std::string Path(getHost().getDriver().Dir); 325 Path += "/../libexec"; 326 getProgramPaths().push_back(Path); 327 328 getProgramPaths().push_back(getHost().getDriver().Dir); 329} 330 331Generic_GCC::~Generic_GCC() { 332 // Free tool implementations. 333 for (llvm::DenseMap<unsigned, Tool*>::iterator 334 it = Tools.begin(), ie = Tools.end(); it != ie; ++it) 335 delete it->second; 336} 337 338Tool &Generic_GCC::SelectTool(const Compilation &C, 339 const JobAction &JA) const { 340 Action::ActionClass Key; 341 if (getHost().getDriver().ShouldUseClangCompiler(C, JA, getTriple())) 342 Key = Action::AnalyzeJobClass; 343 else 344 Key = JA.getKind(); 345 346 Tool *&T = Tools[Key]; 347 if (!T) { 348 switch (Key) { 349 case Action::InputClass: 350 case Action::BindArchClass: 351 assert(0 && "Invalid tool kind."); 352 case Action::PreprocessJobClass: 353 T = new tools::gcc::Preprocess(*this); break; 354 case Action::PrecompileJobClass: 355 T = new tools::gcc::Precompile(*this); break; 356 case Action::AnalyzeJobClass: 357 T = new tools::Clang(*this); break; 358 case Action::CompileJobClass: 359 T = new tools::gcc::Compile(*this); break; 360 case Action::AssembleJobClass: 361 T = new tools::gcc::Assemble(*this); break; 362 case Action::LinkJobClass: 363 T = new tools::gcc::Link(*this); break; 364 365 // This is a bit ungeneric, but the only platform using a driver 366 // driver is Darwin. 367 case Action::LipoJobClass: 368 T = new tools::darwin::Lipo(*this); break; 369 } 370 } 371 372 return *T; 373} 374 375bool Generic_GCC::IsMathErrnoDefault() const { 376 return true; 377} 378 379bool Generic_GCC::IsUnwindTablesDefault() const { 380 // FIXME: Gross; we should probably have some separate target 381 // definition, possibly even reusing the one in clang. 382 return getArchName() == "x86_64"; 383} 384 385const char *Generic_GCC::GetDefaultRelocationModel() const { 386 return "static"; 387} 388 389const char *Generic_GCC::GetForcedPicModel() const { 390 return 0; 391} 392 393DerivedArgList *Generic_GCC::TranslateArgs(InputArgList &Args) const { 394 return new DerivedArgList(Args, true); 395} 396 397/// OpenBSD - OpenBSD tool chain which can call as(1) and ld(1) directly. 398 399OpenBSD::OpenBSD(const HostInfo &Host, const llvm::Triple& Triple) 400 : Generic_GCC(Host, Triple) { 401 getFilePaths().push_back(getHost().getDriver().Dir + "/../lib"); 402 getFilePaths().push_back("/usr/lib"); 403} 404 405Tool &OpenBSD::SelectTool(const Compilation &C, const JobAction &JA) const { 406 Action::ActionClass Key; 407 if (getHost().getDriver().ShouldUseClangCompiler(C, JA, getTriple())) 408 Key = Action::AnalyzeJobClass; 409 else 410 Key = JA.getKind(); 411 412 Tool *&T = Tools[Key]; 413 if (!T) { 414 switch (Key) { 415 case Action::AssembleJobClass: 416 T = new tools::openbsd::Assemble(*this); break; 417 case Action::LinkJobClass: 418 T = new tools::openbsd::Link(*this); break; 419 default: 420 T = &Generic_GCC::SelectTool(C, JA); 421 } 422 } 423 424 return *T; 425} 426 427/// FreeBSD - FreeBSD tool chain which can call as(1) and ld(1) directly. 428 429FreeBSD::FreeBSD(const HostInfo &Host, const llvm::Triple& Triple, bool Lib32) 430 : Generic_GCC(Host, Triple) { 431 if (Lib32) { 432 getFilePaths().push_back(getHost().getDriver().Dir + "/../lib32"); 433 getFilePaths().push_back("/usr/lib32"); 434 } else { 435 getFilePaths().push_back(getHost().getDriver().Dir + "/../lib"); 436 getFilePaths().push_back("/usr/lib"); 437 } 438} 439 440Tool &FreeBSD::SelectTool(const Compilation &C, const JobAction &JA) const { 441 Action::ActionClass Key; 442 if (getHost().getDriver().ShouldUseClangCompiler(C, JA, getTriple())) 443 Key = Action::AnalyzeJobClass; 444 else 445 Key = JA.getKind(); 446 447 Tool *&T = Tools[Key]; 448 if (!T) { 449 switch (Key) { 450 case Action::AssembleJobClass: 451 T = new tools::freebsd::Assemble(*this); break; 452 case Action::LinkJobClass: 453 T = new tools::freebsd::Link(*this); break; 454 default: 455 T = &Generic_GCC::SelectTool(C, JA); 456 } 457 } 458 459 return *T; 460} 461 462/// AuroraUX - AuroraUX tool chain which can call as(1) and ld(1) directly. 463 464AuroraUX::AuroraUX(const HostInfo &Host, const llvm::Triple& Triple) 465 : Generic_GCC(Host, Triple) { 466 467 // Path mangling to find libexec 468 std::string Path(getHost().getDriver().Dir); 469 470 Path += "/../libexec"; 471 getProgramPaths().push_back(Path); 472 getProgramPaths().push_back(getHost().getDriver().Dir); 473 474 getFilePaths().push_back(getHost().getDriver().Dir + "/../lib"); 475 getFilePaths().push_back("/usr/lib"); 476 getFilePaths().push_back("/usr/sfw/lib"); 477 getFilePaths().push_back("/opt/gcc4/lib"); 478 479} 480 481Tool &AuroraUX::SelectTool(const Compilation &C, const JobAction &JA) const { 482 Action::ActionClass Key; 483 if (getHost().getDriver().ShouldUseClangCompiler(C, JA, getTriple())) 484 Key = Action::AnalyzeJobClass; 485 else 486 Key = JA.getKind(); 487 488 Tool *&T = Tools[Key]; 489 if (!T) { 490 switch (Key) { 491 case Action::AssembleJobClass: 492 T = new tools::auroraux::Assemble(*this); break; 493 case Action::LinkJobClass: 494 T = new tools::auroraux::Link(*this); break; 495 default: 496 T = &Generic_GCC::SelectTool(C, JA); 497 } 498 } 499 500 return *T; 501} 502 503 504/// Linux toolchain (very bare-bones at the moment). 505 506Linux::Linux(const HostInfo &Host, const llvm::Triple& Triple) 507 : Generic_GCC(Host, Triple) { 508 getFilePaths().push_back(getHost().getDriver().Dir + "/../lib/clang/1.0/"); 509 getFilePaths().push_back("/lib/"); 510 getFilePaths().push_back("/usr/lib/"); 511 512 // Depending on the Linux distribution, any combination of lib{,32,64} is 513 // possible. E.g. Debian uses lib and lib32 for mixed i386/x86-64 systems, 514 // openSUSE uses lib and lib64 for the same purpose. 515 getFilePaths().push_back("/lib32/"); 516 getFilePaths().push_back("/usr/lib32/"); 517 getFilePaths().push_back("/lib64/"); 518 getFilePaths().push_back("/usr/lib64/"); 519 520 // FIXME: Figure out some way to get gcc's libdir 521 // (e.g. /usr/lib/gcc/i486-linux-gnu/4.3/ for Ubuntu 32-bit); we need 522 // crtbegin.o/crtend.o/etc., and want static versions of various 523 // libraries. If we had our own crtbegin.o/crtend.o/etc, we could probably 524 // get away with using shared versions in /usr/lib, though. 525 // We could fall back to the approach we used for includes (a massive 526 // list), but that's messy at best. 527} 528 529/// DragonFly - DragonFly tool chain which can call as(1) and ld(1) directly. 530 531DragonFly::DragonFly(const HostInfo &Host, const llvm::Triple& Triple) 532 : Generic_GCC(Host, Triple) { 533 534 // Path mangling to find libexec 535 std::string Path(getHost().getDriver().Dir); 536 537 Path += "/../libexec"; 538 getProgramPaths().push_back(Path); 539 getProgramPaths().push_back(getHost().getDriver().Dir); 540 541 getFilePaths().push_back(getHost().getDriver().Dir + "/../lib"); 542 getFilePaths().push_back("/usr/lib"); 543 getFilePaths().push_back("/usr/lib/gcc41"); 544} 545 546Tool &DragonFly::SelectTool(const Compilation &C, const JobAction &JA) const { 547 Action::ActionClass Key; 548 if (getHost().getDriver().ShouldUseClangCompiler(C, JA, getTriple())) 549 Key = Action::AnalyzeJobClass; 550 else 551 Key = JA.getKind(); 552 553 Tool *&T = Tools[Key]; 554 if (!T) { 555 switch (Key) { 556 case Action::AssembleJobClass: 557 T = new tools::dragonfly::Assemble(*this); break; 558 case Action::LinkJobClass: 559 T = new tools::dragonfly::Link(*this); break; 560 default: 561 T = &Generic_GCC::SelectTool(C, JA); 562 } 563 } 564 565 return *T; 566} 567