ToolChains.cpp revision 219073
1234353Sdim//===--- ToolChains.cpp - ToolChain Implementations -----------------------===// 2207618Srdivacky// 3207618Srdivacky// The LLVM Compiler Infrastructure 4207618Srdivacky// 5207618Srdivacky// This file is distributed under the University of Illinois Open Source 6207618Srdivacky// License. See LICENSE.TXT for details. 7207618Srdivacky// 8207618Srdivacky//===----------------------------------------------------------------------===// 9207618Srdivacky 10207618Srdivacky#include "ToolChains.h" 11207618Srdivacky 12207618Srdivacky#include "clang/Driver/Arg.h" 13207618Srdivacky#include "clang/Driver/ArgList.h" 14207618Srdivacky#include "clang/Driver/Compilation.h" 15234353Sdim#include "clang/Driver/Driver.h" 16207618Srdivacky#include "clang/Driver/DriverDiagnostic.h" 17207618Srdivacky#include "clang/Driver/HostInfo.h" 18207618Srdivacky#include "clang/Driver/OptTable.h" 19207618Srdivacky#include "clang/Driver/Option.h" 20207618Srdivacky#include "clang/Driver/Options.h" 21207618Srdivacky#include "clang/Basic/Version.h" 22207618Srdivacky 23218893Sdim#include "llvm/ADT/SmallString.h" 24207618Srdivacky#include "llvm/ADT/StringExtras.h" 25207618Srdivacky#include "llvm/Support/ErrorHandling.h" 26207618Srdivacky#include "llvm/Support/FileSystem.h" 27207618Srdivacky#include "llvm/Support/MemoryBuffer.h" 28207618Srdivacky#include "llvm/Support/raw_ostream.h" 29207618Srdivacky#include "llvm/Support/Path.h" 30207618Srdivacky#include "llvm/Support/system_error.h" 31207618Srdivacky 32207618Srdivacky#include <cstdlib> // ::getenv 33207618Srdivacky 34207618Srdivacky#ifndef CLANG_PREFIX 35226633Sdim#define CLANG_PREFIX 36207618Srdivacky#endif 37207618Srdivacky 38207618Srdivackyusing namespace clang::driver; 39207618Srdivackyusing namespace clang::driver::toolchains; 40207618Srdivacky 41207618Srdivacky/// Darwin - Darwin tool chain for i386 and x86_64. 42207618Srdivacky 43207618SrdivackyDarwin::Darwin(const HostInfo &Host, const llvm::Triple& Triple) 44226633Sdim : ToolChain(Host, Triple), TargetInitialized(false) 45207618Srdivacky{ 46207618Srdivacky // Compute the initial Darwin version based on the host. 47207618Srdivacky bool HadExtra; 48207618Srdivacky std::string OSName = Triple.getOSName(); 49207618Srdivacky if (!Driver::GetReleaseVersion(&OSName[6], 50218893Sdim DarwinVersion[0], DarwinVersion[1], 51218893Sdim DarwinVersion[2], HadExtra)) 52207618Srdivacky getDriver().Diag(clang::diag::err_drv_invalid_darwin_version) << OSName; 53207618Srdivacky 54207618Srdivacky llvm::raw_string_ostream(MacosxVersionMin) 55207618Srdivacky << "10." << std::max(0, (int)DarwinVersion[0] - 4) << '.' 56226633Sdim << DarwinVersion[1]; 57226633Sdim} 58207618Srdivacky 59207618Srdivackytypes::ID Darwin::LookupTypeForExtension(const char *Ext) const { 60218893Sdim types::ID Ty = types::lookupTypeForExtension(Ext); 61218893Sdim 62207618Srdivacky // Darwin always preprocesses assembly files (unless -x is used explicitly). 63207618Srdivacky if (Ty == types::TY_PP_Asm) 64207618Srdivacky return types::TY_Asm; 65207618Srdivacky 66207618Srdivacky return Ty; 67207618Srdivacky} 68207618Srdivacky 69207618Srdivackybool Darwin::HasNativeLLVMSupport() const { 70207618Srdivacky return true; 71207618Srdivacky} 72207618Srdivacky 73207618Srdivacky// FIXME: Can we tablegen this? 74207618Srdivackystatic const char *GetArmArchForMArch(llvm::StringRef Value) { 75207618Srdivacky if (Value == "armv6k") 76226633Sdim return "armv6"; 77207618Srdivacky 78207618Srdivacky if (Value == "armv5tej") 79207618Srdivacky return "armv5"; 80207618Srdivacky 81226633Sdim if (Value == "xscale") 82207618Srdivacky return "xscale"; 83207618Srdivacky 84207618Srdivacky if (Value == "armv4t") 85207618Srdivacky return "armv4t"; 86207618Srdivacky 87207618Srdivacky if (Value == "armv7" || Value == "armv7-a" || Value == "armv7-r" || 88207618Srdivacky Value == "armv7-m" || Value == "armv7a" || Value == "armv7r" || 89207618Srdivacky Value == "armv7m") 90207618Srdivacky return "armv7"; 91207618Srdivacky 92226633Sdim return 0; 93226633Sdim} 94207618Srdivacky 95207618Srdivacky// FIXME: Can we tablegen this? 96207618Srdivackystatic const char *GetArmArchForMCpu(llvm::StringRef Value) { 97207618Srdivacky if (Value == "arm10tdmi" || Value == "arm1020t" || Value == "arm9e" || 98207618Srdivacky Value == "arm946e-s" || Value == "arm966e-s" || 99207618Srdivacky Value == "arm968e-s" || Value == "arm10e" || 100207618Srdivacky Value == "arm1020e" || Value == "arm1022e" || Value == "arm926ej-s" || 101207618Srdivacky Value == "arm1026ej-s") 102207618Srdivacky return "armv5"; 103207618Srdivacky 104207618Srdivacky if (Value == "xscale") 105207618Srdivacky return "xscale"; 106207618Srdivacky 107207618Srdivacky if (Value == "arm1136j-s" || Value == "arm1136jf-s" || 108207618Srdivacky Value == "arm1176jz-s" || Value == "arm1176jzf-s") 109207618Srdivacky return "armv6"; 110207618Srdivacky 111207618Srdivacky if (Value == "cortex-a8" || Value == "cortex-r4" || Value == "cortex-m3") 112207618Srdivacky return "armv7"; 113207618Srdivacky 114212904Sdim return 0; 115207618Srdivacky} 116207618Srdivacky 117207618Srdivackyllvm::StringRef Darwin::getDarwinArchName(const ArgList &Args) const { 118207618Srdivacky switch (getTriple().getArch()) { 119207618Srdivacky default: 120207618Srdivacky return getArchName(); 121207618Srdivacky 122207618Srdivacky case llvm::Triple::arm: { 123207618Srdivacky if (const Arg *A = Args.getLastArg(options::OPT_march_EQ)) 124207618Srdivacky if (const char *Arch = GetArmArchForMArch(A->getValue(Args))) 125207618Srdivacky return Arch; 126207618Srdivacky 127207618Srdivacky if (const Arg *A = Args.getLastArg(options::OPT_mcpu_EQ)) 128207618Srdivacky if (const char *Arch = GetArmArchForMCpu(A->getValue(Args))) 129207618Srdivacky return Arch; 130218893Sdim 131207618Srdivacky return "arm"; 132207618Srdivacky } 133207618Srdivacky } 134207618Srdivacky} 135207618Srdivacky 136207618SrdivackyDarwinGCC::DarwinGCC(const HostInfo &Host, const llvm::Triple& Triple) 137207618Srdivacky : Darwin(Host, Triple) 138207618Srdivacky{ 139207618Srdivacky // We can only work with 4.2.1 currently. 140207618Srdivacky GCCVersion[0] = 4; 141207618Srdivacky GCCVersion[1] = 2; 142207618Srdivacky GCCVersion[2] = 1; 143207618Srdivacky 144207618Srdivacky // Set up the tool chain paths to match gcc. 145207618Srdivacky ToolChainDir = "i686-apple-darwin"; 146207618Srdivacky ToolChainDir += llvm::utostr(DarwinVersion[0]); 147207618Srdivacky ToolChainDir += "/"; 148207618Srdivacky ToolChainDir += llvm::utostr(GCCVersion[0]); 149207618Srdivacky ToolChainDir += '.'; 150207618Srdivacky ToolChainDir += llvm::utostr(GCCVersion[1]); 151207618Srdivacky ToolChainDir += '.'; 152207618Srdivacky ToolChainDir += llvm::utostr(GCCVersion[2]); 153207618Srdivacky 154234353Sdim // Try the next major version if that tool chain dir is invalid. 155234353Sdim std::string Tmp = "/usr/lib/gcc/" + ToolChainDir; 156234353Sdim bool Exists; 157234353Sdim if (llvm::sys::fs::exists(Tmp, Exists) || Exists) { 158234353Sdim std::string Next = "i686-apple-darwin"; 159234353Sdim Next += llvm::utostr(DarwinVersion[0] + 1); 160234353Sdim Next += "/"; 161234353Sdim Next += llvm::utostr(GCCVersion[0]); 162234353Sdim Next += '.'; 163234353Sdim Next += llvm::utostr(GCCVersion[1]); 164234353Sdim Next += '.'; 165234353Sdim Next += llvm::utostr(GCCVersion[2]); 166234353Sdim 167234353Sdim // Use that if it exists, otherwise hope the user isn't linking. 168234353Sdim // 169234353Sdim // FIXME: Drop dependency on gcc's tool chain. 170234353Sdim Tmp = "/usr/lib/gcc/" + Next; 171207618Srdivacky if (!llvm::sys::fs::exists(Tmp, Exists) && Exists) 172207618Srdivacky ToolChainDir = Next; 173207618Srdivacky } 174234353Sdim 175234353Sdim std::string Path; 176234353Sdim if (getArchName() == "x86_64") { 177234353Sdim Path = getDriver().Dir; 178234353Sdim Path += "/../lib/gcc/"; 179234353Sdim Path += ToolChainDir; 180234353Sdim Path += "/x86_64"; 181234353Sdim getFilePaths().push_back(Path); 182234353Sdim 183234353Sdim Path = "/usr/lib/gcc/"; 184234353Sdim Path += ToolChainDir; 185234353Sdim Path += "/x86_64"; 186207618Srdivacky getFilePaths().push_back(Path); 187207618Srdivacky } 188207618Srdivacky 189207618Srdivacky Path = getDriver().Dir; 190207618Srdivacky Path += "/../lib/gcc/"; 191207618Srdivacky Path += ToolChainDir; 192207618Srdivacky getFilePaths().push_back(Path); 193207618Srdivacky 194207618Srdivacky Path = "/usr/lib/gcc/"; 195207618Srdivacky Path += ToolChainDir; 196207618Srdivacky getFilePaths().push_back(Path); 197207618Srdivacky 198207618Srdivacky Path = getDriver().Dir; 199207618Srdivacky Path += "/../libexec/gcc/"; 200207618Srdivacky Path += ToolChainDir; 201207618Srdivacky getProgramPaths().push_back(Path); 202207618Srdivacky 203207618Srdivacky Path = "/usr/libexec/gcc/"; 204207618Srdivacky Path += ToolChainDir; 205207618Srdivacky getProgramPaths().push_back(Path); 206207618Srdivacky 207207618Srdivacky getProgramPaths().push_back(getDriver().getInstalledDir()); 208207618Srdivacky if (getDriver().getInstalledDir() != getDriver().Dir) 209207618Srdivacky getProgramPaths().push_back(getDriver().Dir); 210207618Srdivacky} 211207618Srdivacky 212207618SrdivackyDarwin::~Darwin() { 213207618Srdivacky // Free tool implementations. 214207618Srdivacky for (llvm::DenseMap<unsigned, Tool*>::iterator 215207618Srdivacky it = Tools.begin(), ie = Tools.end(); it != ie; ++it) 216207618Srdivacky delete it->second; 217207618Srdivacky} 218207618Srdivacky 219207618Srdivackystd::string Darwin::ComputeEffectiveClangTriple(const ArgList &Args) const { 220207618Srdivacky llvm::Triple Triple(ComputeLLVMTriple(Args)); 221207618Srdivacky 222207618Srdivacky // If the target isn't initialized (e.g., an unknown Darwin platform, return 223207618Srdivacky // the default triple). 224207618Srdivacky if (!isTargetInitialized()) 225207618Srdivacky return Triple.getTriple(); 226207618Srdivacky 227207618Srdivacky unsigned Version[3]; 228234353Sdim getTargetVersion(Version); 229234353Sdim 230207618Srdivacky // Mangle the target version into the OS triple component. For historical 231207618Srdivacky // reasons that make little sense, the version passed here is the "darwin" 232207618Srdivacky // version, which drops the 10 and offsets by 4. See inverse code when 233207618Srdivacky // setting the OS version preprocessor define. 234234353Sdim if (!isTargetIPhoneOS()) { 235207618Srdivacky Version[0] = Version[1] + 4; 236207618Srdivacky Version[1] = Version[2]; 237207618Srdivacky Version[2] = 0; 238207618Srdivacky } else { 239207618Srdivacky // Use the environment to communicate that we are targetting iPhoneOS. 240207618Srdivacky Triple.setEnvironmentName("iphoneos"); 241207618Srdivacky } 242207618Srdivacky 243234353Sdim llvm::SmallString<16> Str; 244207618Srdivacky llvm::raw_svector_ostream(Str) << "darwin" << Version[0] 245207618Srdivacky << "." << Version[1] << "." << Version[2]; 246207618Srdivacky Triple.setOSName(Str.str()); 247207618Srdivacky 248207618Srdivacky return Triple.getTriple(); 249207618Srdivacky} 250207618Srdivacky 251207618SrdivackyTool &Darwin::SelectTool(const Compilation &C, const JobAction &JA) const { 252207618Srdivacky Action::ActionClass Key; 253207618Srdivacky if (getDriver().ShouldUseClangCompiler(C, JA, getTriple())) 254207618Srdivacky Key = Action::AnalyzeJobClass; 255207618Srdivacky else 256207618Srdivacky Key = JA.getKind(); 257221345Sdim 258234353Sdim // FIXME: This doesn't belong here, but ideally we will support static soon 259207618Srdivacky // anyway. 260207618Srdivacky bool HasStatic = (C.getArgs().hasArg(options::OPT_mkernel) || 261207618Srdivacky C.getArgs().hasArg(options::OPT_static) || 262207618Srdivacky C.getArgs().hasArg(options::OPT_fapple_kext)); 263207618Srdivacky bool IsIADefault = IsIntegratedAssemblerDefault() && !HasStatic; 264207618Srdivacky bool UseIntegratedAs = C.getArgs().hasFlag(options::OPT_integrated_as, 265207618Srdivacky options::OPT_no_integrated_as, 266207618Srdivacky IsIADefault); 267207618Srdivacky 268207618Srdivacky Tool *&T = Tools[Key]; 269207618Srdivacky if (!T) { 270207618Srdivacky switch (Key) { 271207618Srdivacky case Action::InputClass: 272207618Srdivacky case Action::BindArchClass: 273207618Srdivacky assert(0 && "Invalid tool kind."); 274207618Srdivacky case Action::PreprocessJobClass: 275207618Srdivacky T = new tools::darwin::Preprocess(*this); break; 276207618Srdivacky case Action::AnalyzeJobClass: 277207618Srdivacky T = new tools::Clang(*this); break; 278207618Srdivacky case Action::PrecompileJobClass: 279207618Srdivacky case Action::CompileJobClass: 280207618Srdivacky T = new tools::darwin::Compile(*this); break; 281207618Srdivacky case Action::AssembleJobClass: { 282207618Srdivacky if (UseIntegratedAs) 283207618Srdivacky T = new tools::ClangAs(*this); 284207618Srdivacky else 285207618Srdivacky T = new tools::darwin::Assemble(*this); 286207618Srdivacky break; 287207618Srdivacky } 288207618Srdivacky case Action::LinkJobClass: 289207618Srdivacky T = new tools::darwin::Link(*this); break; 290207618Srdivacky case Action::LipoJobClass: 291207618Srdivacky T = new tools::darwin::Lipo(*this); break; 292218893Sdim case Action::DsymutilJobClass: 293234353Sdim T = new tools::darwin::Dsymutil(*this); break; 294218893Sdim } 295218893Sdim } 296218893Sdim 297218893Sdim return *T; 298234353Sdim} 299218893Sdim 300218893Sdimvoid DarwinGCC::AddLinkSearchPathArgs(const ArgList &Args, 301218893Sdim ArgStringList &CmdArgs) const { 302218893Sdim std::string Tmp; 303218893Sdim 304218893Sdim // FIXME: Derive these correctly. 305218893Sdim if (getArchName() == "x86_64") { 306218893Sdim CmdArgs.push_back(Args.MakeArgString("-L/usr/lib/gcc/" + ToolChainDir + 307234353Sdim "/x86_64")); 308218893Sdim // Intentionally duplicated for (temporary) gcc bug compatibility. 309 CmdArgs.push_back(Args.MakeArgString("-L/usr/lib/gcc/" + ToolChainDir + 310 "/x86_64")); 311 } 312 313 CmdArgs.push_back(Args.MakeArgString("-L/usr/lib/" + ToolChainDir)); 314 315 Tmp = getDriver().Dir + "/../lib/gcc/" + ToolChainDir; 316 bool Exists; 317 if (!llvm::sys::fs::exists(Tmp, Exists) && Exists) 318 CmdArgs.push_back(Args.MakeArgString("-L" + Tmp)); 319 Tmp = getDriver().Dir + "/../lib/gcc"; 320 if (!llvm::sys::fs::exists(Tmp, Exists) && Exists) 321 CmdArgs.push_back(Args.MakeArgString("-L" + Tmp)); 322 CmdArgs.push_back(Args.MakeArgString("-L/usr/lib/gcc/" + ToolChainDir)); 323 // Intentionally duplicated for (temporary) gcc bug compatibility. 324 CmdArgs.push_back(Args.MakeArgString("-L/usr/lib/gcc/" + ToolChainDir)); 325 Tmp = getDriver().Dir + "/../lib/" + ToolChainDir; 326 if (!llvm::sys::fs::exists(Tmp, Exists) && Exists) 327 CmdArgs.push_back(Args.MakeArgString("-L" + Tmp)); 328 Tmp = getDriver().Dir + "/../lib"; 329 if (!llvm::sys::fs::exists(Tmp, Exists) && Exists) 330 CmdArgs.push_back(Args.MakeArgString("-L" + Tmp)); 331 CmdArgs.push_back(Args.MakeArgString("-L/usr/lib/gcc/" + ToolChainDir + 332 "/../../../" + ToolChainDir)); 333 CmdArgs.push_back(Args.MakeArgString("-L/usr/lib/gcc/" + ToolChainDir + 334 "/../../..")); 335} 336 337void DarwinGCC::AddLinkRuntimeLibArgs(const ArgList &Args, 338 ArgStringList &CmdArgs) const { 339 // Note that this routine is only used for targetting OS X. 340 341 // Derived from libgcc and lib specs but refactored. 342 if (Args.hasArg(options::OPT_static)) { 343 CmdArgs.push_back("-lgcc_static"); 344 } else { 345 if (Args.hasArg(options::OPT_static_libgcc)) { 346 CmdArgs.push_back("-lgcc_eh"); 347 } else if (Args.hasArg(options::OPT_miphoneos_version_min_EQ)) { 348 // Derived from darwin_iphoneos_libgcc spec. 349 if (isTargetIPhoneOS()) { 350 CmdArgs.push_back("-lgcc_s.1"); 351 } else { 352 CmdArgs.push_back("-lgcc_s.10.5"); 353 } 354 } else if (Args.hasArg(options::OPT_shared_libgcc) || 355 Args.hasFlag(options::OPT_fexceptions, 356 options::OPT_fno_exceptions) || 357 Args.hasArg(options::OPT_fgnu_runtime)) { 358 // FIXME: This is probably broken on 10.3? 359 if (isMacosxVersionLT(10, 5)) 360 CmdArgs.push_back("-lgcc_s.10.4"); 361 else if (isMacosxVersionLT(10, 6)) 362 CmdArgs.push_back("-lgcc_s.10.5"); 363 } else { 364 if (isMacosxVersionLT(10, 3, 9)) 365 ; // Do nothing. 366 else if (isMacosxVersionLT(10, 5)) 367 CmdArgs.push_back("-lgcc_s.10.4"); 368 else if (isMacosxVersionLT(10, 6)) 369 CmdArgs.push_back("-lgcc_s.10.5"); 370 } 371 372 if (isTargetIPhoneOS() || isMacosxVersionLT(10, 6)) { 373 CmdArgs.push_back("-lgcc"); 374 CmdArgs.push_back("-lSystem"); 375 } else { 376 CmdArgs.push_back("-lSystem"); 377 CmdArgs.push_back("-lgcc"); 378 } 379 } 380} 381 382DarwinClang::DarwinClang(const HostInfo &Host, const llvm::Triple& Triple) 383 : Darwin(Host, Triple) 384{ 385 getProgramPaths().push_back(getDriver().getInstalledDir()); 386 if (getDriver().getInstalledDir() != getDriver().Dir) 387 getProgramPaths().push_back(getDriver().Dir); 388 389 // We expect 'as', 'ld', etc. to be adjacent to our install dir. 390 getProgramPaths().push_back(getDriver().getInstalledDir()); 391 if (getDriver().getInstalledDir() != getDriver().Dir) 392 getProgramPaths().push_back(getDriver().Dir); 393 394 // For fallback, we need to know how to find the GCC cc1 executables, so we 395 // also add the GCC libexec paths. This is legiy code that can be removed once 396 // fallback is no longer useful. 397 std::string ToolChainDir = "i686-apple-darwin"; 398 ToolChainDir += llvm::utostr(DarwinVersion[0]); 399 ToolChainDir += "/4.2.1"; 400 401 std::string Path = getDriver().Dir; 402 Path += "/../libexec/gcc/"; 403 Path += ToolChainDir; 404 getProgramPaths().push_back(Path); 405 406 Path = "/usr/libexec/gcc/"; 407 Path += ToolChainDir; 408 getProgramPaths().push_back(Path); 409} 410 411void DarwinClang::AddLinkSearchPathArgs(const ArgList &Args, 412 ArgStringList &CmdArgs) const { 413 // The Clang toolchain uses explicit paths for internal libraries. 414 415 // Unfortunately, we still might depend on a few of the libraries that are 416 // only available in the gcc library directory (in particular 417 // libstdc++.dylib). For now, hardcode the path to the known install location. 418 llvm::sys::Path P(getDriver().Dir); 419 P.eraseComponent(); // .../usr/bin -> ../usr 420 P.appendComponent("lib"); 421 P.appendComponent("gcc"); 422 switch (getTriple().getArch()) { 423 default: 424 assert(0 && "Invalid Darwin arch!"); 425 case llvm::Triple::x86: 426 case llvm::Triple::x86_64: 427 P.appendComponent("i686-apple-darwin10"); 428 break; 429 case llvm::Triple::arm: 430 case llvm::Triple::thumb: 431 P.appendComponent("arm-apple-darwin10"); 432 break; 433 case llvm::Triple::ppc: 434 case llvm::Triple::ppc64: 435 P.appendComponent("powerpc-apple-darwin10"); 436 break; 437 } 438 P.appendComponent("4.2.1"); 439 440 // Determine the arch specific GCC subdirectory. 441 const char *ArchSpecificDir = 0; 442 switch (getTriple().getArch()) { 443 default: 444 break; 445 case llvm::Triple::arm: 446 case llvm::Triple::thumb: { 447 std::string Triple = ComputeLLVMTriple(Args); 448 llvm::StringRef TripleStr = Triple; 449 if (TripleStr.startswith("armv5") || TripleStr.startswith("thumbv5")) 450 ArchSpecificDir = "v5"; 451 else if (TripleStr.startswith("armv6") || TripleStr.startswith("thumbv6")) 452 ArchSpecificDir = "v6"; 453 else if (TripleStr.startswith("armv7") || TripleStr.startswith("thumbv7")) 454 ArchSpecificDir = "v7"; 455 break; 456 } 457 case llvm::Triple::ppc64: 458 ArchSpecificDir = "ppc64"; 459 break; 460 case llvm::Triple::x86_64: 461 ArchSpecificDir = "x86_64"; 462 break; 463 } 464 465 if (ArchSpecificDir) { 466 P.appendComponent(ArchSpecificDir); 467 bool Exists; 468 if (!llvm::sys::fs::exists(P.str(), Exists) && Exists) 469 CmdArgs.push_back(Args.MakeArgString("-L" + P.str())); 470 P.eraseComponent(); 471 } 472 473 bool Exists; 474 if (!llvm::sys::fs::exists(P.str(), Exists) && Exists) 475 CmdArgs.push_back(Args.MakeArgString("-L" + P.str())); 476} 477 478void DarwinClang::AddLinkRuntimeLibArgs(const ArgList &Args, 479 ArgStringList &CmdArgs) const { 480 // Darwin doesn't support real static executables, don't link any runtime 481 // libraries with -static. 482 if (Args.hasArg(options::OPT_static)) 483 return; 484 485 // Reject -static-libgcc for now, we can deal with this when and if someone 486 // cares. This is useful in situations where someone wants to statically link 487 // something like libstdc++, and needs its runtime support routines. 488 if (const Arg *A = Args.getLastArg(options::OPT_static_libgcc)) { 489 getDriver().Diag(clang::diag::err_drv_unsupported_opt) 490 << A->getAsString(Args); 491 return; 492 } 493 494 // Otherwise link libSystem, then the dynamic runtime library, and finally any 495 // target specific static runtime library. 496 CmdArgs.push_back("-lSystem"); 497 498 // Select the dynamic runtime library and the target specific static library. 499 const char *DarwinStaticLib = 0; 500 if (isTargetIPhoneOS()) { 501 CmdArgs.push_back("-lgcc_s.1"); 502 503 // We may need some static functions for armv6/thumb which are required to 504 // be in the same linkage unit as their caller. 505 if (getDarwinArchName(Args) == "armv6") 506 DarwinStaticLib = "libclang_rt.armv6.a"; 507 } else { 508 // The dynamic runtime library was merged with libSystem for 10.6 and 509 // beyond; only 10.4 and 10.5 need an additional runtime library. 510 if (isMacosxVersionLT(10, 5)) 511 CmdArgs.push_back("-lgcc_s.10.4"); 512 else if (isMacosxVersionLT(10, 6)) 513 CmdArgs.push_back("-lgcc_s.10.5"); 514 515 // For OS X, we thought we would only need a static runtime library when 516 // targetting 10.4, to provide versions of the static functions which were 517 // omitted from 10.4.dylib. 518 // 519 // Unfortunately, that turned out to not be true, because Darwin system 520 // headers can still use eprintf on i386, and it is not exported from 521 // libSystem. Therefore, we still must provide a runtime library just for 522 // the tiny tiny handful of projects that *might* use that symbol. 523 if (isMacosxVersionLT(10, 5)) { 524 DarwinStaticLib = "libclang_rt.10.4.a"; 525 } else { 526 if (getTriple().getArch() == llvm::Triple::x86) 527 DarwinStaticLib = "libclang_rt.eprintf.a"; 528 } 529 } 530 531 /// Add the target specific static library, if needed. 532 if (DarwinStaticLib) { 533 llvm::sys::Path P(getDriver().ResourceDir); 534 P.appendComponent("lib"); 535 P.appendComponent("darwin"); 536 P.appendComponent(DarwinStaticLib); 537 538 // For now, allow missing resource libraries to support developers who may 539 // not have compiler-rt checked out or integrated into their build. 540 bool Exists; 541 if (!llvm::sys::fs::exists(P.str(), Exists) && Exists) 542 CmdArgs.push_back(Args.MakeArgString(P.str())); 543 } 544} 545 546void Darwin::AddDeploymentTarget(DerivedArgList &Args) const { 547 const OptTable &Opts = getDriver().getOpts(); 548 549 Arg *OSXVersion = Args.getLastArg(options::OPT_mmacosx_version_min_EQ); 550 Arg *iPhoneVersion = Args.getLastArg(options::OPT_miphoneos_version_min_EQ); 551 if (OSXVersion && iPhoneVersion) { 552 getDriver().Diag(clang::diag::err_drv_argument_not_allowed_with) 553 << OSXVersion->getAsString(Args) 554 << iPhoneVersion->getAsString(Args); 555 iPhoneVersion = 0; 556 } else if (!OSXVersion && !iPhoneVersion) { 557 // If neither OS X nor iPhoneOS targets were specified, check for 558 // environment defines. 559 const char *OSXTarget = ::getenv("MACOSX_DEPLOYMENT_TARGET"); 560 const char *iPhoneOSTarget = ::getenv("IPHONEOS_DEPLOYMENT_TARGET"); 561 562 // Ignore empty strings. 563 if (OSXTarget && OSXTarget[0] == '\0') 564 OSXTarget = 0; 565 if (iPhoneOSTarget && iPhoneOSTarget[0] == '\0') 566 iPhoneOSTarget = 0; 567 568 // Diagnose conflicting deployment targets, and choose default platform 569 // based on the tool chain. 570 // 571 // FIXME: Don't hardcode default here. 572 if (OSXTarget && iPhoneOSTarget) { 573 // FIXME: We should see if we can get away with warning or erroring on 574 // this. Perhaps put under -pedantic? 575 if (getTriple().getArch() == llvm::Triple::arm || 576 getTriple().getArch() == llvm::Triple::thumb) 577 OSXTarget = 0; 578 else 579 iPhoneOSTarget = 0; 580 } 581 582 if (OSXTarget) { 583 const Option *O = Opts.getOption(options::OPT_mmacosx_version_min_EQ); 584 OSXVersion = Args.MakeJoinedArg(0, O, OSXTarget); 585 Args.append(OSXVersion); 586 } else if (iPhoneOSTarget) { 587 const Option *O = Opts.getOption(options::OPT_miphoneos_version_min_EQ); 588 iPhoneVersion = Args.MakeJoinedArg(0, O, iPhoneOSTarget); 589 Args.append(iPhoneVersion); 590 } else { 591 // Otherwise, assume we are targeting OS X. 592 const Option *O = Opts.getOption(options::OPT_mmacosx_version_min_EQ); 593 OSXVersion = Args.MakeJoinedArg(0, O, MacosxVersionMin); 594 Args.append(OSXVersion); 595 } 596 } 597 598 // Set the tool chain target information. 599 unsigned Major, Minor, Micro; 600 bool HadExtra; 601 if (OSXVersion) { 602 assert(!iPhoneVersion && "Unknown target platform!"); 603 if (!Driver::GetReleaseVersion(OSXVersion->getValue(Args), Major, Minor, 604 Micro, HadExtra) || HadExtra || 605 Major != 10 || Minor >= 10 || Micro >= 10) 606 getDriver().Diag(clang::diag::err_drv_invalid_version_number) 607 << OSXVersion->getAsString(Args); 608 } else { 609 assert(iPhoneVersion && "Unknown target platform!"); 610 if (!Driver::GetReleaseVersion(iPhoneVersion->getValue(Args), Major, Minor, 611 Micro, HadExtra) || HadExtra || 612 Major >= 10 || Minor >= 100 || Micro >= 100) 613 getDriver().Diag(clang::diag::err_drv_invalid_version_number) 614 << iPhoneVersion->getAsString(Args); 615 } 616 setTarget(iPhoneVersion, Major, Minor, Micro); 617} 618 619void DarwinClang::AddCXXStdlibLibArgs(const ArgList &Args, 620 ArgStringList &CmdArgs) const { 621 CXXStdlibType Type = GetCXXStdlibType(Args); 622 623 switch (Type) { 624 case ToolChain::CST_Libcxx: 625 CmdArgs.push_back("-lc++"); 626 break; 627 628 case ToolChain::CST_Libstdcxx: { 629 // Unfortunately, -lstdc++ doesn't always exist in the standard search path; 630 // it was previously found in the gcc lib dir. However, for all the Darwin 631 // platforms we care about it was -lstdc++.6, so we search for that 632 // explicitly if we can't see an obvious -lstdc++ candidate. 633 634 // Check in the sysroot first. 635 bool Exists; 636 if (const Arg *A = Args.getLastArg(options::OPT_isysroot)) { 637 llvm::sys::Path P(A->getValue(Args)); 638 P.appendComponent("usr"); 639 P.appendComponent("lib"); 640 P.appendComponent("libstdc++.dylib"); 641 642 if (llvm::sys::fs::exists(P.str(), Exists) || !Exists) { 643 P.eraseComponent(); 644 P.appendComponent("libstdc++.6.dylib"); 645 if (!llvm::sys::fs::exists(P.str(), Exists) && Exists) { 646 CmdArgs.push_back(Args.MakeArgString(P.str())); 647 return; 648 } 649 } 650 } 651 652 // Otherwise, look in the root. 653 if ((llvm::sys::fs::exists("/usr/lib/libstdc++.dylib", Exists) || !Exists)&& 654 (!llvm::sys::fs::exists("/usr/lib/libstdc++.6.dylib", Exists) && Exists)){ 655 CmdArgs.push_back("/usr/lib/libstdc++.6.dylib"); 656 return; 657 } 658 659 // Otherwise, let the linker search. 660 CmdArgs.push_back("-lstdc++"); 661 break; 662 } 663 } 664} 665 666void DarwinClang::AddCCKextLibArgs(const ArgList &Args, 667 ArgStringList &CmdArgs) const { 668 669 // For Darwin platforms, use the compiler-rt-based support library 670 // instead of the gcc-provided one (which is also incidentally 671 // only present in the gcc lib dir, which makes it hard to find). 672 673 llvm::sys::Path P(getDriver().ResourceDir); 674 P.appendComponent("lib"); 675 P.appendComponent("darwin"); 676 P.appendComponent("libclang_rt.cc_kext.a"); 677 678 // For now, allow missing resource libraries to support developers who may 679 // not have compiler-rt checked out or integrated into their build. 680 bool Exists; 681 if (!llvm::sys::fs::exists(P.str(), Exists) && Exists) 682 CmdArgs.push_back(Args.MakeArgString(P.str())); 683} 684 685DerivedArgList *Darwin::TranslateArgs(const DerivedArgList &Args, 686 const char *BoundArch) const { 687 DerivedArgList *DAL = new DerivedArgList(Args.getBaseArgs()); 688 const OptTable &Opts = getDriver().getOpts(); 689 690 // FIXME: We really want to get out of the tool chain level argument 691 // translation business, as it makes the driver functionality much 692 // more opaque. For now, we follow gcc closely solely for the 693 // purpose of easily achieving feature parity & testability. Once we 694 // have something that works, we should reevaluate each translation 695 // and try to push it down into tool specific logic. 696 697 for (ArgList::const_iterator it = Args.begin(), 698 ie = Args.end(); it != ie; ++it) { 699 Arg *A = *it; 700 701 if (A->getOption().matches(options::OPT_Xarch__)) { 702 // FIXME: Canonicalize name. 703 if (getArchName() != A->getValue(Args, 0)) 704 continue; 705 706 Arg *OriginalArg = A; 707 unsigned Index = Args.getBaseArgs().MakeIndex(A->getValue(Args, 1)); 708 unsigned Prev = Index; 709 Arg *XarchArg = Opts.ParseOneArg(Args, Index); 710 711 // If the argument parsing failed or more than one argument was 712 // consumed, the -Xarch_ argument's parameter tried to consume 713 // extra arguments. Emit an error and ignore. 714 // 715 // We also want to disallow any options which would alter the 716 // driver behavior; that isn't going to work in our model. We 717 // use isDriverOption() as an approximation, although things 718 // like -O4 are going to slip through. 719 if (!XarchArg || Index > Prev + 1 || 720 XarchArg->getOption().isDriverOption()) { 721 getDriver().Diag(clang::diag::err_drv_invalid_Xarch_argument) 722 << A->getAsString(Args); 723 continue; 724 } 725 726 XarchArg->setBaseArg(A); 727 A = XarchArg; 728 729 DAL->AddSynthesizedArg(A); 730 731 // Linker input arguments require custom handling. The problem is that we 732 // have already constructed the phase actions, so we can not treat them as 733 // "input arguments". 734 if (A->getOption().isLinkerInput()) { 735 // Convert the argument into individual Zlinker_input_args. 736 for (unsigned i = 0, e = A->getNumValues(); i != e; ++i) { 737 DAL->AddSeparateArg(OriginalArg, 738 Opts.getOption(options::OPT_Zlinker_input), 739 A->getValue(Args, i)); 740 741 } 742 continue; 743 } 744 } 745 746 // Sob. These is strictly gcc compatible for the time being. Apple 747 // gcc translates options twice, which means that self-expanding 748 // options add duplicates. 749 switch ((options::ID) A->getOption().getID()) { 750 default: 751 DAL->append(A); 752 break; 753 754 case options::OPT_mkernel: 755 case options::OPT_fapple_kext: 756 DAL->append(A); 757 DAL->AddFlagArg(A, Opts.getOption(options::OPT_static)); 758 DAL->AddFlagArg(A, Opts.getOption(options::OPT_static)); 759 break; 760 761 case options::OPT_dependency_file: 762 DAL->AddSeparateArg(A, Opts.getOption(options::OPT_MF), 763 A->getValue(Args)); 764 break; 765 766 case options::OPT_gfull: 767 DAL->AddFlagArg(A, Opts.getOption(options::OPT_g_Flag)); 768 DAL->AddFlagArg(A, 769 Opts.getOption(options::OPT_fno_eliminate_unused_debug_symbols)); 770 break; 771 772 case options::OPT_gused: 773 DAL->AddFlagArg(A, Opts.getOption(options::OPT_g_Flag)); 774 DAL->AddFlagArg(A, 775 Opts.getOption(options::OPT_feliminate_unused_debug_symbols)); 776 break; 777 778 case options::OPT_fterminated_vtables: 779 case options::OPT_findirect_virtual_calls: 780 DAL->AddFlagArg(A, Opts.getOption(options::OPT_fapple_kext)); 781 DAL->AddFlagArg(A, Opts.getOption(options::OPT_static)); 782 break; 783 784 case options::OPT_shared: 785 DAL->AddFlagArg(A, Opts.getOption(options::OPT_dynamiclib)); 786 break; 787 788 case options::OPT_fconstant_cfstrings: 789 DAL->AddFlagArg(A, Opts.getOption(options::OPT_mconstant_cfstrings)); 790 break; 791 792 case options::OPT_fno_constant_cfstrings: 793 DAL->AddFlagArg(A, Opts.getOption(options::OPT_mno_constant_cfstrings)); 794 break; 795 796 case options::OPT_Wnonportable_cfstrings: 797 DAL->AddFlagArg(A, 798 Opts.getOption(options::OPT_mwarn_nonportable_cfstrings)); 799 break; 800 801 case options::OPT_Wno_nonportable_cfstrings: 802 DAL->AddFlagArg(A, 803 Opts.getOption(options::OPT_mno_warn_nonportable_cfstrings)); 804 break; 805 806 case options::OPT_fpascal_strings: 807 DAL->AddFlagArg(A, Opts.getOption(options::OPT_mpascal_strings)); 808 break; 809 810 case options::OPT_fno_pascal_strings: 811 DAL->AddFlagArg(A, Opts.getOption(options::OPT_mno_pascal_strings)); 812 break; 813 } 814 } 815 816 if (getTriple().getArch() == llvm::Triple::x86 || 817 getTriple().getArch() == llvm::Triple::x86_64) 818 if (!Args.hasArgNoClaim(options::OPT_mtune_EQ)) 819 DAL->AddJoinedArg(0, Opts.getOption(options::OPT_mtune_EQ), "core2"); 820 821 // Add the arch options based on the particular spelling of -arch, to match 822 // how the driver driver works. 823 if (BoundArch) { 824 llvm::StringRef Name = BoundArch; 825 const Option *MCpu = Opts.getOption(options::OPT_mcpu_EQ); 826 const Option *MArch = Opts.getOption(options::OPT_march_EQ); 827 828 // This code must be kept in sync with LLVM's getArchTypeForDarwinArch, 829 // which defines the list of which architectures we accept. 830 if (Name == "ppc") 831 ; 832 else if (Name == "ppc601") 833 DAL->AddJoinedArg(0, MCpu, "601"); 834 else if (Name == "ppc603") 835 DAL->AddJoinedArg(0, MCpu, "603"); 836 else if (Name == "ppc604") 837 DAL->AddJoinedArg(0, MCpu, "604"); 838 else if (Name == "ppc604e") 839 DAL->AddJoinedArg(0, MCpu, "604e"); 840 else if (Name == "ppc750") 841 DAL->AddJoinedArg(0, MCpu, "750"); 842 else if (Name == "ppc7400") 843 DAL->AddJoinedArg(0, MCpu, "7400"); 844 else if (Name == "ppc7450") 845 DAL->AddJoinedArg(0, MCpu, "7450"); 846 else if (Name == "ppc970") 847 DAL->AddJoinedArg(0, MCpu, "970"); 848 849 else if (Name == "ppc64") 850 DAL->AddFlagArg(0, Opts.getOption(options::OPT_m64)); 851 852 else if (Name == "i386") 853 ; 854 else if (Name == "i486") 855 DAL->AddJoinedArg(0, MArch, "i486"); 856 else if (Name == "i586") 857 DAL->AddJoinedArg(0, MArch, "i586"); 858 else if (Name == "i686") 859 DAL->AddJoinedArg(0, MArch, "i686"); 860 else if (Name == "pentium") 861 DAL->AddJoinedArg(0, MArch, "pentium"); 862 else if (Name == "pentium2") 863 DAL->AddJoinedArg(0, MArch, "pentium2"); 864 else if (Name == "pentpro") 865 DAL->AddJoinedArg(0, MArch, "pentiumpro"); 866 else if (Name == "pentIIm3") 867 DAL->AddJoinedArg(0, MArch, "pentium2"); 868 869 else if (Name == "x86_64") 870 DAL->AddFlagArg(0, Opts.getOption(options::OPT_m64)); 871 872 else if (Name == "arm") 873 DAL->AddJoinedArg(0, MArch, "armv4t"); 874 else if (Name == "armv4t") 875 DAL->AddJoinedArg(0, MArch, "armv4t"); 876 else if (Name == "armv5") 877 DAL->AddJoinedArg(0, MArch, "armv5tej"); 878 else if (Name == "xscale") 879 DAL->AddJoinedArg(0, MArch, "xscale"); 880 else if (Name == "armv6") 881 DAL->AddJoinedArg(0, MArch, "armv6k"); 882 else if (Name == "armv7") 883 DAL->AddJoinedArg(0, MArch, "armv7a"); 884 885 else 886 llvm_unreachable("invalid Darwin arch"); 887 } 888 889 // Add an explicit version min argument for the deployment target. We do this 890 // after argument translation because -Xarch_ arguments may add a version min 891 // argument. 892 AddDeploymentTarget(*DAL); 893 894 return DAL; 895} 896 897bool Darwin::IsUnwindTablesDefault() const { 898 // FIXME: Gross; we should probably have some separate target 899 // definition, possibly even reusing the one in clang. 900 return getArchName() == "x86_64"; 901} 902 903bool Darwin::UseDwarfDebugFlags() const { 904 if (const char *S = ::getenv("RC_DEBUG_OPTIONS")) 905 return S[0] != '\0'; 906 return false; 907} 908 909bool Darwin::UseSjLjExceptions() const { 910 // Darwin uses SjLj exceptions on ARM. 911 return (getTriple().getArch() == llvm::Triple::arm || 912 getTriple().getArch() == llvm::Triple::thumb); 913} 914 915const char *Darwin::GetDefaultRelocationModel() const { 916 return "pic"; 917} 918 919const char *Darwin::GetForcedPicModel() const { 920 if (getArchName() == "x86_64") 921 return "pic"; 922 return 0; 923} 924 925bool Darwin::SupportsObjCGC() const { 926 // Garbage collection is supported everywhere except on iPhone OS. 927 return !isTargetIPhoneOS(); 928} 929 930std::string 931Darwin_Generic_GCC::ComputeEffectiveClangTriple(const ArgList &Args) const { 932 return ComputeLLVMTriple(Args); 933} 934 935/// Generic_GCC - A tool chain using the 'gcc' command to perform 936/// all subcommands; this relies on gcc translating the majority of 937/// command line options. 938 939Generic_GCC::Generic_GCC(const HostInfo &Host, const llvm::Triple& Triple) 940 : ToolChain(Host, Triple) { 941 getProgramPaths().push_back(getDriver().getInstalledDir()); 942 if (getDriver().getInstalledDir() != getDriver().Dir.c_str()) 943 getProgramPaths().push_back(getDriver().Dir); 944} 945 946Generic_GCC::~Generic_GCC() { 947 // Free tool implementations. 948 for (llvm::DenseMap<unsigned, Tool*>::iterator 949 it = Tools.begin(), ie = Tools.end(); it != ie; ++it) 950 delete it->second; 951} 952 953Tool &Generic_GCC::SelectTool(const Compilation &C, 954 const JobAction &JA) const { 955 Action::ActionClass Key; 956 if (getDriver().ShouldUseClangCompiler(C, JA, getTriple())) 957 Key = Action::AnalyzeJobClass; 958 else 959 Key = JA.getKind(); 960 961 Tool *&T = Tools[Key]; 962 if (!T) { 963 switch (Key) { 964 case Action::InputClass: 965 case Action::BindArchClass: 966 assert(0 && "Invalid tool kind."); 967 case Action::PreprocessJobClass: 968 T = new tools::gcc::Preprocess(*this); break; 969 case Action::PrecompileJobClass: 970 T = new tools::gcc::Precompile(*this); break; 971 case Action::AnalyzeJobClass: 972 T = new tools::Clang(*this); break; 973 case Action::CompileJobClass: 974 T = new tools::gcc::Compile(*this); break; 975 case Action::AssembleJobClass: 976 T = new tools::gcc::Assemble(*this); break; 977 case Action::LinkJobClass: 978 T = new tools::gcc::Link(*this); break; 979 980 // This is a bit ungeneric, but the only platform using a driver 981 // driver is Darwin. 982 case Action::LipoJobClass: 983 T = new tools::darwin::Lipo(*this); break; 984 case Action::DsymutilJobClass: 985 T = new tools::darwin::Dsymutil(*this); break; 986 } 987 } 988 989 return *T; 990} 991 992bool Generic_GCC::IsUnwindTablesDefault() const { 993 // FIXME: Gross; we should probably have some separate target 994 // definition, possibly even reusing the one in clang. 995 return getArchName() == "x86_64"; 996} 997 998const char *Generic_GCC::GetDefaultRelocationModel() const { 999 return "static"; 1000} 1001 1002const char *Generic_GCC::GetForcedPicModel() const { 1003 return 0; 1004} 1005 1006/// TCEToolChain - A tool chain using the llvm bitcode tools to perform 1007/// all subcommands. See http://tce.cs.tut.fi for our peculiar target. 1008/// Currently does not support anything else but compilation. 1009 1010TCEToolChain::TCEToolChain(const HostInfo &Host, const llvm::Triple& Triple) 1011 : ToolChain(Host, Triple) { 1012 // Path mangling to find libexec 1013 std::string Path(getDriver().Dir); 1014 1015 Path += "/../libexec"; 1016 getProgramPaths().push_back(Path); 1017} 1018 1019TCEToolChain::~TCEToolChain() { 1020 for (llvm::DenseMap<unsigned, Tool*>::iterator 1021 it = Tools.begin(), ie = Tools.end(); it != ie; ++it) 1022 delete it->second; 1023} 1024 1025bool TCEToolChain::IsMathErrnoDefault() const { 1026 return true; 1027} 1028 1029bool TCEToolChain::IsUnwindTablesDefault() const { 1030 return false; 1031} 1032 1033const char *TCEToolChain::GetDefaultRelocationModel() const { 1034 return "static"; 1035} 1036 1037const char *TCEToolChain::GetForcedPicModel() const { 1038 return 0; 1039} 1040 1041Tool &TCEToolChain::SelectTool(const Compilation &C, 1042 const JobAction &JA) const { 1043 Action::ActionClass Key; 1044 Key = Action::AnalyzeJobClass; 1045 1046 Tool *&T = Tools[Key]; 1047 if (!T) { 1048 switch (Key) { 1049 case Action::PreprocessJobClass: 1050 T = new tools::gcc::Preprocess(*this); break; 1051 case Action::AnalyzeJobClass: 1052 T = new tools::Clang(*this); break; 1053 default: 1054 assert(false && "Unsupported action for TCE target."); 1055 } 1056 } 1057 return *T; 1058} 1059 1060/// OpenBSD - OpenBSD tool chain which can call as(1) and ld(1) directly. 1061 1062OpenBSD::OpenBSD(const HostInfo &Host, const llvm::Triple& Triple) 1063 : Generic_ELF(Host, Triple) { 1064 getFilePaths().push_back(getDriver().Dir + "/../lib"); 1065 getFilePaths().push_back("/usr/lib"); 1066} 1067 1068Tool &OpenBSD::SelectTool(const Compilation &C, const JobAction &JA) const { 1069 Action::ActionClass Key; 1070 if (getDriver().ShouldUseClangCompiler(C, JA, getTriple())) 1071 Key = Action::AnalyzeJobClass; 1072 else 1073 Key = JA.getKind(); 1074 1075 bool UseIntegratedAs = C.getArgs().hasFlag(options::OPT_integrated_as, 1076 options::OPT_no_integrated_as, 1077 IsIntegratedAssemblerDefault()); 1078 1079 Tool *&T = Tools[Key]; 1080 if (!T) { 1081 switch (Key) { 1082 case Action::AssembleJobClass: { 1083 if (UseIntegratedAs) 1084 T = new tools::ClangAs(*this); 1085 else 1086 T = new tools::openbsd::Assemble(*this); 1087 break; 1088 } 1089 case Action::LinkJobClass: 1090 T = new tools::openbsd::Link(*this); break; 1091 default: 1092 T = &Generic_GCC::SelectTool(C, JA); 1093 } 1094 } 1095 1096 return *T; 1097} 1098 1099/// FreeBSD - FreeBSD tool chain which can call as(1) and ld(1) directly. 1100 1101FreeBSD::FreeBSD(const HostInfo &Host, const llvm::Triple& Triple) 1102 : Generic_ELF(Host, Triple) { 1103 1104 // Determine if we are compiling 32-bit code on an x86_64 platform. 1105 bool Lib32 = false; 1106 if (Triple.getArch() == llvm::Triple::x86 && 1107 llvm::Triple(getDriver().DefaultHostTriple).getArch() == 1108 llvm::Triple::x86_64) 1109 Lib32 = true; 1110 1111 if (Lib32) { 1112 getFilePaths().push_back(CLANG_PREFIX "/usr/lib32"); 1113 } else { 1114 getFilePaths().push_back(CLANG_PREFIX "/usr/lib"); 1115 } 1116} 1117 1118Tool &FreeBSD::SelectTool(const Compilation &C, const JobAction &JA) const { 1119 Action::ActionClass Key; 1120 if (getDriver().ShouldUseClangCompiler(C, JA, getTriple())) 1121 Key = Action::AnalyzeJobClass; 1122 else 1123 Key = JA.getKind(); 1124 1125 bool UseIntegratedAs = C.getArgs().hasFlag(options::OPT_integrated_as, 1126 options::OPT_no_integrated_as, 1127 IsIntegratedAssemblerDefault()); 1128 1129 Tool *&T = Tools[Key]; 1130 if (!T) { 1131 switch (Key) { 1132 case Action::AssembleJobClass: 1133 if (UseIntegratedAs) 1134 T = new tools::ClangAs(*this); 1135 else 1136 T = new tools::freebsd::Assemble(*this); 1137 break; 1138 case Action::LinkJobClass: 1139 T = new tools::freebsd::Link(*this); break; 1140 default: 1141 T = &Generic_GCC::SelectTool(C, JA); 1142 } 1143 } 1144 1145 return *T; 1146} 1147 1148/// NetBSD - NetBSD tool chain which can call as(1) and ld(1) directly. 1149 1150NetBSD::NetBSD(const HostInfo &Host, const llvm::Triple& Triple) 1151 : Generic_ELF(Host, Triple) { 1152 1153 // Determine if we are compiling 32-bit code on an x86_64 platform. 1154 bool Lib32 = false; 1155 if (Triple.getArch() == llvm::Triple::x86 && 1156 llvm::Triple(getDriver().DefaultHostTriple).getArch() == 1157 llvm::Triple::x86_64) 1158 Lib32 = true; 1159 1160 getProgramPaths().push_back(getDriver().Dir + "/../libexec"); 1161 getProgramPaths().push_back("/usr/libexec"); 1162 if (Lib32) { 1163 getFilePaths().push_back("/usr/lib/i386"); 1164 } else { 1165 getFilePaths().push_back("/usr/lib"); 1166 } 1167} 1168 1169Tool &NetBSD::SelectTool(const Compilation &C, const JobAction &JA) const { 1170 Action::ActionClass Key; 1171 if (getDriver().ShouldUseClangCompiler(C, JA, getTriple())) 1172 Key = Action::AnalyzeJobClass; 1173 else 1174 Key = JA.getKind(); 1175 1176 bool UseIntegratedAs = C.getArgs().hasFlag(options::OPT_integrated_as, 1177 options::OPT_no_integrated_as, 1178 IsIntegratedAssemblerDefault()); 1179 1180 Tool *&T = Tools[Key]; 1181 if (!T) { 1182 switch (Key) { 1183 case Action::AssembleJobClass: 1184 if (UseIntegratedAs) 1185 T = new tools::ClangAs(*this); 1186 else 1187 T = new tools::netbsd::Assemble(*this); 1188 break; 1189 case Action::LinkJobClass: 1190 T = new tools::netbsd::Link(*this); break; 1191 default: 1192 T = &Generic_GCC::SelectTool(C, JA); 1193 } 1194 } 1195 1196 return *T; 1197} 1198 1199/// Minix - Minix tool chain which can call as(1) and ld(1) directly. 1200 1201Minix::Minix(const HostInfo &Host, const llvm::Triple& Triple) 1202 : Generic_GCC(Host, Triple) { 1203 getFilePaths().push_back(getDriver().Dir + "/../lib"); 1204 getFilePaths().push_back("/usr/lib"); 1205 getFilePaths().push_back("/usr/gnu/lib"); 1206 getFilePaths().push_back("/usr/gnu/lib/gcc/i686-pc-minix/4.4.3"); 1207} 1208 1209Tool &Minix::SelectTool(const Compilation &C, const JobAction &JA) const { 1210 Action::ActionClass Key; 1211 if (getDriver().ShouldUseClangCompiler(C, JA, getTriple())) 1212 Key = Action::AnalyzeJobClass; 1213 else 1214 Key = JA.getKind(); 1215 1216 Tool *&T = Tools[Key]; 1217 if (!T) { 1218 switch (Key) { 1219 case Action::AssembleJobClass: 1220 T = new tools::minix::Assemble(*this); break; 1221 case Action::LinkJobClass: 1222 T = new tools::minix::Link(*this); break; 1223 default: 1224 T = &Generic_GCC::SelectTool(C, JA); 1225 } 1226 } 1227 1228 return *T; 1229} 1230 1231/// AuroraUX - AuroraUX tool chain which can call as(1) and ld(1) directly. 1232 1233AuroraUX::AuroraUX(const HostInfo &Host, const llvm::Triple& Triple) 1234 : Generic_GCC(Host, Triple) { 1235 1236 getProgramPaths().push_back(getDriver().getInstalledDir()); 1237 if (getDriver().getInstalledDir() != getDriver().Dir.c_str()) 1238 getProgramPaths().push_back(getDriver().Dir); 1239 1240 getFilePaths().push_back(getDriver().Dir + "/../lib"); 1241 getFilePaths().push_back("/usr/lib"); 1242 getFilePaths().push_back("/usr/sfw/lib"); 1243 getFilePaths().push_back("/opt/gcc4/lib"); 1244 getFilePaths().push_back("/opt/gcc4/lib/gcc/i386-pc-solaris2.11/4.2.4"); 1245 1246} 1247 1248Tool &AuroraUX::SelectTool(const Compilation &C, const JobAction &JA) const { 1249 Action::ActionClass Key; 1250 if (getDriver().ShouldUseClangCompiler(C, JA, getTriple())) 1251 Key = Action::AnalyzeJobClass; 1252 else 1253 Key = JA.getKind(); 1254 1255 Tool *&T = Tools[Key]; 1256 if (!T) { 1257 switch (Key) { 1258 case Action::AssembleJobClass: 1259 T = new tools::auroraux::Assemble(*this); break; 1260 case Action::LinkJobClass: 1261 T = new tools::auroraux::Link(*this); break; 1262 default: 1263 T = &Generic_GCC::SelectTool(C, JA); 1264 } 1265 } 1266 1267 return *T; 1268} 1269 1270 1271/// Linux toolchain (very bare-bones at the moment). 1272 1273enum LinuxDistro { 1274 DebianLenny, 1275 DebianSqueeze, 1276 Exherbo, 1277 Fedora13, 1278 Fedora14, 1279 OpenSuse11_3, 1280 UbuntuJaunty, 1281 UbuntuKarmic, 1282 UbuntuLucid, 1283 UbuntuMaverick, 1284 UnknownDistro 1285}; 1286 1287static bool IsFedora(enum LinuxDistro Distro) { 1288 return Distro == Fedora13 || Distro == Fedora14; 1289} 1290 1291static bool IsOpenSuse(enum LinuxDistro Distro) { 1292 return Distro == OpenSuse11_3; 1293} 1294 1295static bool IsDebian(enum LinuxDistro Distro) { 1296 return Distro == DebianLenny || Distro == DebianSqueeze; 1297} 1298 1299static bool IsUbuntu(enum LinuxDistro Distro) { 1300 return Distro == UbuntuLucid || Distro == UbuntuMaverick || 1301 Distro == UbuntuJaunty || Distro == UbuntuKarmic; 1302} 1303 1304static bool IsDebianBased(enum LinuxDistro Distro) { 1305 return IsDebian(Distro) || IsUbuntu(Distro); 1306} 1307 1308static bool HasMultilib(llvm::Triple::ArchType Arch, enum LinuxDistro Distro) { 1309 if (Arch == llvm::Triple::x86_64) { 1310 bool Exists; 1311 if (Distro == Exherbo && 1312 (llvm::sys::fs::exists("/usr/lib32/libc.so", Exists) || !Exists)) 1313 return false; 1314 1315 return true; 1316 } 1317 if (Arch == llvm::Triple::x86 && IsDebianBased(Distro)) 1318 return true; 1319 return false; 1320} 1321 1322static LinuxDistro DetectLinuxDistro(llvm::Triple::ArchType Arch) { 1323 llvm::OwningPtr<llvm::MemoryBuffer> File; 1324 if (!llvm::MemoryBuffer::getFile("/etc/lsb-release", File)) { 1325 llvm::StringRef Data = File.get()->getBuffer(); 1326 llvm::SmallVector<llvm::StringRef, 8> Lines; 1327 Data.split(Lines, "\n"); 1328 for (unsigned int i = 0, s = Lines.size(); i < s; ++ i) { 1329 if (Lines[i] == "DISTRIB_CODENAME=maverick") 1330 return UbuntuMaverick; 1331 else if (Lines[i] == "DISTRIB_CODENAME=lucid") 1332 return UbuntuLucid; 1333 else if (Lines[i] == "DISTRIB_CODENAME=jaunty") 1334 return UbuntuJaunty; 1335 else if (Lines[i] == "DISTRIB_CODENAME=karmic") 1336 return UbuntuKarmic; 1337 } 1338 return UnknownDistro; 1339 } 1340 1341 if (!llvm::MemoryBuffer::getFile("/etc/redhat-release", File)) { 1342 llvm::StringRef Data = File.get()->getBuffer(); 1343 if (Data.startswith("Fedora release 14 (Laughlin)")) 1344 return Fedora14; 1345 else if (Data.startswith("Fedora release 13 (Goddard)")) 1346 return Fedora13; 1347 return UnknownDistro; 1348 } 1349 1350 if (!llvm::MemoryBuffer::getFile("/etc/debian_version", File)) { 1351 llvm::StringRef Data = File.get()->getBuffer(); 1352 if (Data[0] == '5') 1353 return DebianLenny; 1354 else if (Data.startswith("squeeze/sid")) 1355 return DebianSqueeze; 1356 return UnknownDistro; 1357 } 1358 1359 if (!llvm::MemoryBuffer::getFile("/etc/SuSE-release", File)) { 1360 llvm::StringRef Data = File.get()->getBuffer(); 1361 if (Data.startswith("openSUSE 11.3")) 1362 return OpenSuse11_3; 1363 return UnknownDistro; 1364 } 1365 1366 bool Exists; 1367 if (!llvm::sys::fs::exists("/etc/exherbo-release", Exists) && Exists) 1368 return Exherbo; 1369 1370 return UnknownDistro; 1371} 1372 1373Linux::Linux(const HostInfo &Host, const llvm::Triple &Triple) 1374 : Generic_ELF(Host, Triple) { 1375 llvm::Triple::ArchType Arch = 1376 llvm::Triple(getDriver().DefaultHostTriple).getArch(); 1377 1378 std::string Suffix32 = ""; 1379 if (Arch == llvm::Triple::x86_64) 1380 Suffix32 = "/32"; 1381 1382 std::string Suffix64 = ""; 1383 if (Arch == llvm::Triple::x86) 1384 Suffix64 = "/64"; 1385 1386 std::string Lib32 = "lib"; 1387 1388 bool Exists; 1389 if (!llvm::sys::fs::exists("/lib32", Exists) && Exists) 1390 Lib32 = "lib32"; 1391 1392 std::string Lib64 = "lib"; 1393 bool Symlink; 1394 if (!llvm::sys::fs::exists("/lib64", Exists) && Exists && 1395 (llvm::sys::fs::is_symlink("/lib64", Symlink) || !Symlink)) 1396 Lib64 = "lib64"; 1397 1398 std::string GccTriple = ""; 1399 if (Arch == llvm::Triple::arm) { 1400 if (!llvm::sys::fs::exists("/usr/lib/gcc/arm-linux-gnueabi", Exists) && 1401 Exists) 1402 GccTriple = "arm-linux-gnueabi"; 1403 } else if (Arch == llvm::Triple::x86_64) { 1404 if (!llvm::sys::fs::exists("/usr/lib/gcc/x86_64-linux-gnu", Exists) && 1405 Exists) 1406 GccTriple = "x86_64-linux-gnu"; 1407 else if (!llvm::sys::fs::exists("/usr/lib/gcc/x86_64-unknown-linux-gnu", 1408 Exists) && Exists) 1409 GccTriple = "x86_64-unknown-linux-gnu"; 1410 else if (!llvm::sys::fs::exists("/usr/lib/gcc/x86_64-pc-linux-gnu", 1411 Exists) && Exists) 1412 GccTriple = "x86_64-pc-linux-gnu"; 1413 else if (!llvm::sys::fs::exists("/usr/lib/gcc/x86_64-redhat-linux", 1414 Exists) && Exists) 1415 GccTriple = "x86_64-redhat-linux"; 1416 else if (!llvm::sys::fs::exists("/usr/lib64/gcc/x86_64-suse-linux", 1417 Exists) && Exists) 1418 GccTriple = "x86_64-suse-linux"; 1419 else if (!llvm::sys::fs::exists("/usr/lib/gcc/x86_64-manbo-linux-gnu", 1420 Exists) && Exists) 1421 GccTriple = "x86_64-manbo-linux-gnu"; 1422 } else if (Arch == llvm::Triple::x86) { 1423 if (!llvm::sys::fs::exists("/usr/lib/gcc/i686-linux-gnu", Exists) && Exists) 1424 GccTriple = "i686-linux-gnu"; 1425 else if (!llvm::sys::fs::exists("/usr/lib/gcc/i686-pc-linux-gnu", Exists) && 1426 Exists) 1427 GccTriple = "i686-pc-linux-gnu"; 1428 else if (!llvm::sys::fs::exists("/usr/lib/gcc/i486-linux-gnu", Exists) && 1429 Exists) 1430 GccTriple = "i486-linux-gnu"; 1431 else if (!llvm::sys::fs::exists("/usr/lib/gcc/i686-redhat-linux", Exists) && 1432 Exists) 1433 GccTriple = "i686-redhat-linux"; 1434 else if (!llvm::sys::fs::exists("/usr/lib/gcc/i586-suse-linux", Exists) && 1435 Exists) 1436 GccTriple = "i586-suse-linux"; 1437 } 1438 1439 const char* GccVersions[] = {"4.5.1", "4.5", "4.4.5", "4.4.4", "4.4.3", "4.4", 1440 "4.3.4", "4.3.3", "4.3.2"}; 1441 std::string Base = ""; 1442 for (unsigned i = 0; i < sizeof(GccVersions)/sizeof(char*); ++i) { 1443 std::string Suffix = GccTriple + "/" + GccVersions[i]; 1444 std::string t1 = "/usr/lib/gcc/" + Suffix; 1445 if (!llvm::sys::fs::exists(t1 + "/crtbegin.o", Exists) && Exists) { 1446 Base = t1; 1447 break; 1448 } 1449 std::string t2 = "/usr/lib64/gcc/" + Suffix; 1450 if (!llvm::sys::fs::exists(t2 + "/crtbegin.o", Exists) && Exists) { 1451 Base = t2; 1452 break; 1453 } 1454 } 1455 1456 path_list &Paths = getFilePaths(); 1457 bool Is32Bits = getArch() == llvm::Triple::x86; 1458 1459 std::string Suffix; 1460 std::string Lib; 1461 1462 if (Is32Bits) { 1463 Suffix = Suffix32; 1464 Lib = Lib32; 1465 } else { 1466 Suffix = Suffix64; 1467 Lib = Lib64; 1468 } 1469 1470 llvm::sys::Path LinkerPath(Base + "/../../../../" + GccTriple + "/bin/ld"); 1471 if (!llvm::sys::fs::exists(LinkerPath.str(), Exists) && Exists) 1472 Linker = LinkerPath.str(); 1473 else 1474 Linker = GetProgramPath("ld"); 1475 1476 LinuxDistro Distro = DetectLinuxDistro(Arch); 1477 1478 if (IsUbuntu(Distro)) { 1479 ExtraOpts.push_back("-z"); 1480 ExtraOpts.push_back("relro"); 1481 } 1482 1483 if (Arch == llvm::Triple::arm) 1484 ExtraOpts.push_back("-X"); 1485 1486 if (IsFedora(Distro) || Distro == UbuntuMaverick) 1487 ExtraOpts.push_back("--hash-style=gnu"); 1488 1489 if (IsDebian(Distro) || Distro == UbuntuLucid || Distro == UbuntuJaunty || 1490 Distro == UbuntuKarmic) 1491 ExtraOpts.push_back("--hash-style=both"); 1492 1493 if (IsFedora(Distro)) 1494 ExtraOpts.push_back("--no-add-needed"); 1495 1496 if (Distro == DebianSqueeze || IsOpenSuse(Distro) || 1497 IsFedora(Distro) || Distro == UbuntuLucid || Distro == UbuntuMaverick || 1498 Distro == UbuntuKarmic) 1499 ExtraOpts.push_back("--build-id"); 1500 1501 Paths.push_back(Base + Suffix); 1502 if (HasMultilib(Arch, Distro)) { 1503 if (IsOpenSuse(Distro) && Is32Bits) 1504 Paths.push_back(Base + "/../../../../" + GccTriple + "/lib/../lib"); 1505 Paths.push_back(Base + "/../../../../" + Lib); 1506 Paths.push_back("/lib/../" + Lib); 1507 Paths.push_back("/usr/lib/../" + Lib); 1508 } 1509 if (!Suffix.empty()) 1510 Paths.push_back(Base); 1511 if (IsOpenSuse(Distro)) 1512 Paths.push_back(Base + "/../../../../" + GccTriple + "/lib"); 1513 Paths.push_back(Base + "/../../.."); 1514 if (Arch == getArch() && IsUbuntu(Distro)) 1515 Paths.push_back("/usr/lib/" + GccTriple); 1516} 1517 1518bool Linux::HasNativeLLVMSupport() const { 1519 return true; 1520} 1521 1522Tool &Linux::SelectTool(const Compilation &C, const JobAction &JA) const { 1523 Action::ActionClass Key; 1524 if (getDriver().ShouldUseClangCompiler(C, JA, getTriple())) 1525 Key = Action::AnalyzeJobClass; 1526 else 1527 Key = JA.getKind(); 1528 1529 bool UseIntegratedAs = C.getArgs().hasFlag(options::OPT_integrated_as, 1530 options::OPT_no_integrated_as, 1531 IsIntegratedAssemblerDefault()); 1532 1533 Tool *&T = Tools[Key]; 1534 if (!T) { 1535 switch (Key) { 1536 case Action::AssembleJobClass: 1537 if (UseIntegratedAs) 1538 T = new tools::ClangAs(*this); 1539 else 1540 T = new tools::linuxtools::Assemble(*this); 1541 break; 1542 case Action::LinkJobClass: 1543 T = new tools::linuxtools::Link(*this); break; 1544 default: 1545 T = &Generic_GCC::SelectTool(C, JA); 1546 } 1547 } 1548 1549 return *T; 1550} 1551 1552/// DragonFly - DragonFly tool chain which can call as(1) and ld(1) directly. 1553 1554DragonFly::DragonFly(const HostInfo &Host, const llvm::Triple& Triple) 1555 : Generic_ELF(Host, Triple) { 1556 1557 // Path mangling to find libexec 1558 getProgramPaths().push_back(getDriver().getInstalledDir()); 1559 if (getDriver().getInstalledDir() != getDriver().Dir.c_str()) 1560 getProgramPaths().push_back(getDriver().Dir); 1561 1562 getFilePaths().push_back(getDriver().Dir + "/../lib"); 1563 getFilePaths().push_back("/usr/lib"); 1564 getFilePaths().push_back("/usr/lib/gcc41"); 1565} 1566 1567Tool &DragonFly::SelectTool(const Compilation &C, const JobAction &JA) const { 1568 Action::ActionClass Key; 1569 if (getDriver().ShouldUseClangCompiler(C, JA, getTriple())) 1570 Key = Action::AnalyzeJobClass; 1571 else 1572 Key = JA.getKind(); 1573 1574 Tool *&T = Tools[Key]; 1575 if (!T) { 1576 switch (Key) { 1577 case Action::AssembleJobClass: 1578 T = new tools::dragonfly::Assemble(*this); break; 1579 case Action::LinkJobClass: 1580 T = new tools::dragonfly::Link(*this); break; 1581 default: 1582 T = &Generic_GCC::SelectTool(C, JA); 1583 } 1584 } 1585 1586 return *T; 1587} 1588 1589Windows::Windows(const HostInfo &Host, const llvm::Triple& Triple) 1590 : ToolChain(Host, Triple) { 1591} 1592 1593Tool &Windows::SelectTool(const Compilation &C, const JobAction &JA) const { 1594 Action::ActionClass Key; 1595 if (getDriver().ShouldUseClangCompiler(C, JA, getTriple())) 1596 Key = Action::AnalyzeJobClass; 1597 else 1598 Key = JA.getKind(); 1599 1600 Tool *&T = Tools[Key]; 1601 if (!T) { 1602 switch (Key) { 1603 case Action::InputClass: 1604 case Action::BindArchClass: 1605 case Action::LipoJobClass: 1606 case Action::DsymutilJobClass: 1607 assert(0 && "Invalid tool kind."); 1608 case Action::PreprocessJobClass: 1609 case Action::PrecompileJobClass: 1610 case Action::AnalyzeJobClass: 1611 case Action::CompileJobClass: 1612 T = new tools::Clang(*this); break; 1613 case Action::AssembleJobClass: 1614 T = new tools::ClangAs(*this); break; 1615 case Action::LinkJobClass: 1616 T = new tools::visualstudio::Link(*this); break; 1617 } 1618 } 1619 1620 return *T; 1621} 1622 1623bool Windows::IsIntegratedAssemblerDefault() const { 1624 return true; 1625} 1626 1627bool Windows::IsUnwindTablesDefault() const { 1628 // FIXME: Gross; we should probably have some separate target 1629 // definition, possibly even reusing the one in clang. 1630 return getArchName() == "x86_64"; 1631} 1632 1633const char *Windows::GetDefaultRelocationModel() const { 1634 return "static"; 1635} 1636 1637const char *Windows::GetForcedPicModel() const { 1638 if (getArchName() == "x86_64") 1639 return "pic"; 1640 return 0; 1641} 1642