ToolChains.cpp revision 1eb4433ac451dc16f4133a88af2d002ac26c58ef
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 std::string Path(getHost().getDriver().Dir); 324 Path += "/../libexec"; 325 getProgramPaths().push_back(Path); 326 327 getProgramPaths().push_back(getHost().getDriver().Dir); 328} 329 330Generic_GCC::~Generic_GCC() { 331 // Free tool implementations. 332 for (llvm::DenseMap<unsigned, Tool*>::iterator 333 it = Tools.begin(), ie = Tools.end(); it != ie; ++it) 334 delete it->second; 335} 336 337Tool &Generic_GCC::SelectTool(const Compilation &C, 338 const JobAction &JA) const { 339 Action::ActionClass Key; 340 if (getHost().getDriver().ShouldUseClangCompiler(C, JA, getTriple())) 341 Key = Action::AnalyzeJobClass; 342 else 343 Key = JA.getKind(); 344 345 Tool *&T = Tools[Key]; 346 if (!T) { 347 switch (Key) { 348 case Action::InputClass: 349 case Action::BindArchClass: 350 assert(0 && "Invalid tool kind."); 351 case Action::PreprocessJobClass: 352 T = new tools::gcc::Preprocess(*this); break; 353 case Action::PrecompileJobClass: 354 T = new tools::gcc::Precompile(*this); break; 355 case Action::AnalyzeJobClass: 356 T = new tools::Clang(*this); break; 357 case Action::CompileJobClass: 358 T = new tools::gcc::Compile(*this); break; 359 case Action::AssembleJobClass: 360 T = new tools::gcc::Assemble(*this); break; 361 case Action::LinkJobClass: 362 T = new tools::gcc::Link(*this); break; 363 364 // This is a bit ungeneric, but the only platform using a driver 365 // driver is Darwin. 366 case Action::LipoJobClass: 367 T = new tools::darwin::Lipo(*this); break; 368 } 369 } 370 371 return *T; 372} 373 374bool Generic_GCC::IsMathErrnoDefault() const { 375 return true; 376} 377 378bool Generic_GCC::IsUnwindTablesDefault() const { 379 // FIXME: Gross; we should probably have some separate target 380 // definition, possibly even reusing the one in clang. 381 return getArchName() == "x86_64"; 382} 383 384const char *Generic_GCC::GetDefaultRelocationModel() const { 385 return "static"; 386} 387 388const char *Generic_GCC::GetForcedPicModel() const { 389 return 0; 390} 391 392DerivedArgList *Generic_GCC::TranslateArgs(InputArgList &Args) const { 393 return new DerivedArgList(Args, true); 394} 395 396/// OpenBSD - OpenBSD tool chain which can call as(1) and ld(1) directly. 397 398OpenBSD::OpenBSD(const HostInfo &Host, const llvm::Triple& Triple) 399 : Generic_GCC(Host, Triple) { 400 getFilePaths().push_back(getHost().getDriver().Dir + "/../lib"); 401 getFilePaths().push_back("/usr/lib"); 402} 403 404Tool &OpenBSD::SelectTool(const Compilation &C, const JobAction &JA) const { 405 Action::ActionClass Key; 406 if (getHost().getDriver().ShouldUseClangCompiler(C, JA, getTriple())) 407 Key = Action::AnalyzeJobClass; 408 else 409 Key = JA.getKind(); 410 411 Tool *&T = Tools[Key]; 412 if (!T) { 413 switch (Key) { 414 case Action::AssembleJobClass: 415 T = new tools::openbsd::Assemble(*this); break; 416 case Action::LinkJobClass: 417 T = new tools::openbsd::Link(*this); break; 418 default: 419 T = &Generic_GCC::SelectTool(C, JA); 420 } 421 } 422 423 return *T; 424} 425 426/// FreeBSD - FreeBSD tool chain which can call as(1) and ld(1) directly. 427 428FreeBSD::FreeBSD(const HostInfo &Host, const llvm::Triple& Triple, bool Lib32) 429 : Generic_GCC(Host, Triple) { 430 if (Lib32) { 431 getFilePaths().push_back(getHost().getDriver().Dir + "/../lib32"); 432 getFilePaths().push_back("/usr/lib32"); 433 } else { 434 getFilePaths().push_back(getHost().getDriver().Dir + "/../lib"); 435 getFilePaths().push_back("/usr/lib"); 436 } 437} 438 439Tool &FreeBSD::SelectTool(const Compilation &C, const JobAction &JA) const { 440 Action::ActionClass Key; 441 if (getHost().getDriver().ShouldUseClangCompiler(C, JA, getTriple())) 442 Key = Action::AnalyzeJobClass; 443 else 444 Key = JA.getKind(); 445 446 Tool *&T = Tools[Key]; 447 if (!T) { 448 switch (Key) { 449 case Action::AssembleJobClass: 450 T = new tools::freebsd::Assemble(*this); break; 451 case Action::LinkJobClass: 452 T = new tools::freebsd::Link(*this); break; 453 default: 454 T = &Generic_GCC::SelectTool(C, JA); 455 } 456 } 457 458 return *T; 459} 460 461/// AuroraUX - AuroraUX tool chain which can call as(1) and ld(1) directly. 462 463AuroraUX::AuroraUX(const HostInfo &Host, const llvm::Triple& Triple) 464 : Generic_GCC(Host, Triple) { 465 466 // Path mangling to find libexec 467 std::string Path(getHost().getDriver().Dir); 468 469 Path += "/../libexec"; 470 getProgramPaths().push_back(Path); 471 getProgramPaths().push_back(getHost().getDriver().Dir); 472 473 getFilePaths().push_back(getHost().getDriver().Dir + "/../lib"); 474 getFilePaths().push_back("/usr/lib"); 475 getFilePaths().push_back("/usr/sfw/lib"); 476 getFilePaths().push_back("/opt/gcc4/lib"); 477 478} 479 480Tool &AuroraUX::SelectTool(const Compilation &C, const JobAction &JA) const { 481 Action::ActionClass Key; 482 if (getHost().getDriver().ShouldUseClangCompiler(C, JA, getTriple())) 483 Key = Action::AnalyzeJobClass; 484 else 485 Key = JA.getKind(); 486 487 Tool *&T = Tools[Key]; 488 if (!T) { 489 switch (Key) { 490 case Action::AssembleJobClass: 491 T = new tools::auroraux::Assemble(*this); break; 492 case Action::LinkJobClass: 493 T = new tools::auroraux::Link(*this); break; 494 default: 495 T = &Generic_GCC::SelectTool(C, JA); 496 } 497 } 498 499 return *T; 500} 501 502 503/// Linux toolchain (very bare-bones at the moment). 504 505Linux::Linux(const HostInfo &Host, const llvm::Triple& Triple) 506 : Generic_GCC(Host, Triple) { 507 getFilePaths().push_back(getHost().getDriver().Dir + "/../lib/clang/1.0/"); 508 getFilePaths().push_back("/lib/"); 509 getFilePaths().push_back("/usr/lib/"); 510 511 // Depending on the Linux distribution, any combination of lib{,32,64} is 512 // possible. E.g. Debian uses lib and lib32 for mixed i386/x86-64 systems, 513 // openSUSE uses lib and lib64 for the same purpose. 514 getFilePaths().push_back("/lib32/"); 515 getFilePaths().push_back("/usr/lib32/"); 516 getFilePaths().push_back("/lib64/"); 517 getFilePaths().push_back("/usr/lib64/"); 518 519 // FIXME: Figure out some way to get gcc's libdir 520 // (e.g. /usr/lib/gcc/i486-linux-gnu/4.3/ for Ubuntu 32-bit); we need 521 // crtbegin.o/crtend.o/etc., and want static versions of various 522 // libraries. If we had our own crtbegin.o/crtend.o/etc, we could probably 523 // get away with using shared versions in /usr/lib, though. 524 // We could fall back to the approach we used for includes (a massive 525 // list), but that's messy at best. 526} 527 528/// DragonFly - DragonFly tool chain which can call as(1) and ld(1) directly. 529 530DragonFly::DragonFly(const HostInfo &Host, const llvm::Triple& Triple) 531 : Generic_GCC(Host, Triple) { 532 533 // Path mangling to find libexec 534 std::string Path(getHost().getDriver().Dir); 535 536 Path += "/../libexec"; 537 getProgramPaths().push_back(Path); 538 getProgramPaths().push_back(getHost().getDriver().Dir); 539 540 getFilePaths().push_back(getHost().getDriver().Dir + "/../lib"); 541 getFilePaths().push_back("/usr/lib"); 542 getFilePaths().push_back("/usr/lib/gcc41"); 543} 544 545Tool &DragonFly::SelectTool(const Compilation &C, const JobAction &JA) const { 546 Action::ActionClass Key; 547 if (getHost().getDriver().ShouldUseClangCompiler(C, JA, getTriple())) 548 Key = Action::AnalyzeJobClass; 549 else 550 Key = JA.getKind(); 551 552 Tool *&T = Tools[Key]; 553 if (!T) { 554 switch (Key) { 555 case Action::AssembleJobClass: 556 T = new tools::dragonfly::Assemble(*this); break; 557 case Action::LinkJobClass: 558 T = new tools::dragonfly::Link(*this); break; 559 default: 560 T = &Generic_GCC::SelectTool(C, JA); 561 } 562 } 563 564 return *T; 565} 566