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