std::unique_ptr<ELFLinkingContext> elf::createMipsLinkingContext(llvm::Triple triple) { if (triple.getArch() == llvm::Triple::mips || triple.getArch() == llvm::Triple::mipsel || triple.getArch() == llvm::Triple::mips64 || triple.getArch() == llvm::Triple::mips64el) return llvm::make_unique<MipsLinkingContext>(triple); return nullptr; }
void GnuLdDriver::addPlatformSearchDirs(ELFLinkingContext &ctx, llvm::Triple &triple, llvm::Triple &baseTriple) { if (triple.getOS() == llvm::Triple::NetBSD && triple.getArch() == llvm::Triple::x86 && baseTriple.getArch() == llvm::Triple::x86_64) { ctx.addSearchPath("=/usr/lib/i386"); return; } ctx.addSearchPath("=/usr/lib"); }
static bool areCompatibleArchitectures(const llvm::Triple &moduleTarget, const llvm::Triple &ctxTarget) { if (moduleTarget.getArch() == ctxTarget.getArch()) return true; auto archPair = std::minmax(moduleTarget.getArch(), ctxTarget.getArch()); if (archPair == std::minmax(llvm::Triple::arm, llvm::Triple::thumb)) return true; if (archPair == std::minmax(llvm::Triple::armeb, llvm::Triple::thumbeb)) return true; return false; }
FreeBSD::FreeBSD(const Driver &D, const llvm::Triple &Triple, const ArgList &Args) : Generic_ELF(D, Triple, Args) { // When targeting 32-bit platforms, look for '/usr/lib32/crt1.o' and fall // back to '/usr/lib' if it doesn't exist. if ((Triple.getArch() == llvm::Triple::x86 || Triple.getArch() == llvm::Triple::mips || Triple.getArch() == llvm::Triple::mipsel || Triple.getArch() == llvm::Triple::ppc) && D.getVFS().exists(getDriver().SysRoot + "/usr/lib32/crt1.o")) getFilePaths().push_back(getDriver().SysRoot + "/usr/lib32"); else getFilePaths().push_back(getDriver().SysRoot + "/usr/lib"); }
static llvm::Optional<llvm::Triple::ArchType> getArchType(const llvm::Triple &triple, StringRef value) { switch (triple.getArch()) { case llvm::Triple::x86: case llvm::Triple::x86_64: if (value == "elf_i386") return llvm::Triple::x86; if (value == "elf_x86_64") return llvm::Triple::x86_64; return llvm::None; case llvm::Triple::mips: case llvm::Triple::mipsel: case llvm::Triple::mips64: case llvm::Triple::mips64el: return llvm::StringSwitch<llvm::Optional<llvm::Triple::ArchType>>(value) .Cases("elf32btsmip", "elf32btsmipn32", llvm::Triple::mips) .Cases("elf32ltsmip", "elf32ltsmipn32", llvm::Triple::mipsel) .Case("elf64btsmip", llvm::Triple::mips64) .Case("elf64ltsmip", llvm::Triple::mips64el) .Default(llvm::None); case llvm::Triple::aarch64: if (value == "aarch64linux") return llvm::Triple::aarch64; return llvm::None; case llvm::Triple::arm: if (value == "armelf_linux_eabi") return llvm::Triple::arm; return llvm::None; default: return llvm::None; } }
MyriadToolChain::MyriadToolChain(const Driver &D, const llvm::Triple &Triple, const ArgList &Args) : Generic_ELF(D, Triple, Args) { // If a target of 'sparc-myriad-elf' is specified to clang, it wants to use // 'sparc-myriad--elf' (note the unknown OS) as the canonical triple. // This won't work to find gcc. Instead we give the installation detector an // extra triple, which is preferable to further hacks of the logic that at // present is based solely on getArch(). In particular, it would be wrong to // choose the myriad installation when targeting a non-myriad sparc install. switch (Triple.getArch()) { default: D.Diag(clang::diag::err_target_unsupported_arch) << Triple.getArchName() << "myriad"; case llvm::Triple::sparc: case llvm::Triple::sparcel: case llvm::Triple::shave: GCCInstallation.init(Triple, Args, {"sparc-myriad-elf"}); } if (GCCInstallation.isValid()) { // This directory contains crt{i,n,begin,end}.o as well as libgcc. // These files are tied to a particular version of gcc. SmallString<128> CompilerSupportDir(GCCInstallation.getInstallPath()); addPathIfExists(D, CompilerSupportDir, getFilePaths()); } // libstd++ and libc++ must both be found in this one place. addPathIfExists(D, D.Dir + "/../sparc-myriad-elf/lib", getFilePaths()); }
static ToolChain::RTTIMode CalculateRTTIMode(const ArgList &Args, const llvm::Triple &Triple, const Arg *CachedRTTIArg) { // Explicit rtti/no-rtti args if (CachedRTTIArg) { if (CachedRTTIArg->getOption().matches(options::OPT_frtti)) return ToolChain::RM_EnabledExplicitly; else return ToolChain::RM_DisabledExplicitly; } // On Cheerp -frtti is disabled by default if (Triple.getArch() == llvm::Triple::cheerp) return ToolChain::RM_DisabledImplicitly; // -frtti is default, except for the PS4 CPU. if (!Triple.isPS4CPU()) return ToolChain::RM_EnabledImplicitly; // On the PS4, turning on c++ exceptions turns on rtti. // We're assuming that, if we see -fexceptions, rtti gets turned on. Arg *Exceptions = Args.getLastArgNoClaim( options::OPT_fcxx_exceptions, options::OPT_fno_cxx_exceptions, options::OPT_fexceptions, options::OPT_fno_exceptions); if (Exceptions && (Exceptions->getOption().matches(options::OPT_fexceptions) || Exceptions->getOption().matches(options::OPT_fcxx_exceptions))) return ToolChain::RM_EnabledImplicitly; return ToolChain::RM_DisabledImplicitly; }
/// Returns the LLVM name of the target CPU to use given the provided /// -mcpu argument and target triple. static std::string getTargetCPU(const std::string &cpu, const llvm::Triple &triple) { if (!cpu.empty()) { if (cpu != "native") return cpu; // FIXME: Reject attempts to use -mcpu=native unless the target matches // the host. std::string hostCPU = llvm::sys::getHostCPUName(); if (!hostCPU.empty() && hostCPU != "generic") return hostCPU; } switch (triple.getArch()) { default: // We don't know about the specifics of this platform, just return the // empty string and let LLVM decide. return cpu; case llvm::Triple::x86: case llvm::Triple::x86_64: return getX86TargetCPU(triple); case llvm::Triple::arm: return getARMTargetCPU(triple); } }
Solaris::Solaris(const Driver &D, const llvm::Triple &Triple, const ArgList &Args) : Generic_ELF(D, Triple, Args) { GCCInstallation.init(Triple, Args); path_list &Paths = getFilePaths(); if (GCCInstallation.isValid()) addPathIfExists(D, GCCInstallation.getInstallPath(), Paths); addPathIfExists(D, getDriver().getInstalledDir(), Paths); if (getDriver().getInstalledDir() != getDriver().Dir) addPathIfExists(D, getDriver().Dir, Paths); addPathIfExists(D, getDriver().SysRoot + getDriver().Dir + "/../lib", Paths); std::string LibPath = "/usr/lib/"; switch (Triple.getArch()) { case llvm::Triple::x86: case llvm::Triple::sparc: break; case llvm::Triple::x86_64: LibPath += "amd64/"; break; case llvm::Triple::sparcv9: LibPath += "sparcv9/"; break; default: llvm_unreachable("Unsupported architecture"); } addPathIfExists(D, getDriver().SysRoot + LibPath, Paths); }
static llvm::Optional<llvm::Triple::ArchType> getArchType(const llvm::Triple &triple, StringRef value) { switch (triple.getArch()) { case llvm::Triple::x86: case llvm::Triple::x86_64: if (value == "elf_i386") return llvm::Triple::x86; if (value == "elf_x86_64") return llvm::Triple::x86_64; return llvm::None; case llvm::Triple::mipsel: case llvm::Triple::mips64el: if (value == "elf32ltsmip") return llvm::Triple::mipsel; if (value == "elf64ltsmip") return llvm::Triple::mips64el; return llvm::None; case llvm::Triple::aarch64: if (value == "aarch64linux") return llvm::Triple::aarch64; return llvm::None; case llvm::Triple::arm: if (value == "armelf_linux_eabi") return llvm::Triple::arm; return llvm::None; default: return llvm::None; } }
/// Sanitizes the MIPS ABI in the feature string. static void addMipsABI(const llvm::Triple &triple, std::vector<std::string> &attrs) { enum ABI { O32 = 1 << 0, N32 = 1 << 1, N64 = 1 << 2, EABI = 1 << 3 }; const bool is64Bit = triple.getArch() == llvm::Triple::mips64 || triple.getArch() == llvm::Triple::mips64el; const uint32_t defaultABI = is64Bit ? N64 : O32; uint32_t bits = defaultABI; auto I = attrs.begin(); while (I != attrs.end()) { std::string str = *I; bool enabled = str[0] == '+'; std::string flag = (str[0] == '+' || str[0] == '-') ? str.substr(1) : str; uint32_t newBit = 0; if (flag == "o32") { newBit = O32; } if (flag == "n32") { newBit = N32; } if (flag == "n64") { newBit = N64; } if (flag == "eabi") { newBit = EABI; } if (newBit) { I = attrs.erase(I); if (enabled) { bits |= newBit; } else { bits &= ~newBit; } } else { ++I; } } switch (bits) { case O32: attrs.push_back("+o32"); break; case N32: attrs.push_back("+n32"); break; case N64: attrs.push_back("+n64"); break; case EABI: attrs.push_back("+eabi"); break; default: error(Loc(), "Only one ABI argument is supported"); fatal(); } if (bits != defaultABI) { attrs.push_back(is64Bit ? "-n64" : "-o32"); } }
static TargetHandlerPtr createTarget(llvm::Triple triple, MipsLinkingContext &ctx) { switch (triple.getArch()) { case llvm::Triple::mipsel: return TargetHandlerPtr(new MipsTargetHandler<Mips32ELType>(ctx)); case llvm::Triple::mips64el: return TargetHandlerPtr(new MipsTargetHandler<Mips64ELType>(ctx)); default: llvm_unreachable("Unhandled arch"); } }
Statement* asmSemantic(AsmStatement *s, Scope *sc) { if (sc->func && sc->func->isSafe()) s->error("inline assembler not allowed in @safe function %s", sc->func->toChars()); bool err = false; llvm::Triple const t = global.params.targetTriple; if (!(t.getArch() == llvm::Triple::x86 || t.getArch() == llvm::Triple::x86_64)) { s->error("inline asm is not supported for the \"%s\" architecture", t.getArchName().str().c_str()); err = true; } if (!global.params.useInlineAsm) { s->error("inline asm is not allowed when the -noasm switch is used"); err = true; } if (err) fatal(); //puts(toChars()); sc->func->hasReturnExp |= 8; // empty statement -- still do the above things because they might be expected? if (!s->tokens) return s; if (!asmparser) { if (t.getArch() == llvm::Triple::x86) asmparser = new AsmParserx8632::AsmParser; else if (t.getArch() == llvm::Triple::x86_64) asmparser = new AsmParserx8664::AsmParser; } asmparser->run(sc, s); return s; }
/// NaCl Toolchain NaClToolChain::NaClToolChain(const Driver &D, const llvm::Triple &Triple, const ArgList &Args) : Generic_ELF(D, Triple, Args) { // Remove paths added by Generic_GCC. NaCl Toolchain cannot use the // default paths, and must instead only use the paths provided // with this toolchain based on architecture. path_list &file_paths = getFilePaths(); path_list &prog_paths = getProgramPaths(); file_paths.clear(); prog_paths.clear(); // Path for library files (libc.a, ...) std::string FilePath(getDriver().Dir + "/../"); // Path for tools (clang, ld, etc..) std::string ProgPath(getDriver().Dir + "/../"); // Path for toolchain libraries (libgcc.a, ...) std::string ToolPath(getDriver().ResourceDir + "/lib/"); switch (Triple.getArch()) { case llvm::Triple::x86: file_paths.push_back(FilePath + "x86_64-nacl/lib32"); file_paths.push_back(FilePath + "i686-nacl/usr/lib"); prog_paths.push_back(ProgPath + "x86_64-nacl/bin"); file_paths.push_back(ToolPath + "i686-nacl"); break; case llvm::Triple::x86_64: file_paths.push_back(FilePath + "x86_64-nacl/lib"); file_paths.push_back(FilePath + "x86_64-nacl/usr/lib"); prog_paths.push_back(ProgPath + "x86_64-nacl/bin"); file_paths.push_back(ToolPath + "x86_64-nacl"); break; case llvm::Triple::arm: file_paths.push_back(FilePath + "arm-nacl/lib"); file_paths.push_back(FilePath + "arm-nacl/usr/lib"); prog_paths.push_back(ProgPath + "arm-nacl/bin"); file_paths.push_back(ToolPath + "arm-nacl"); break; case llvm::Triple::mipsel: file_paths.push_back(FilePath + "mipsel-nacl/lib"); file_paths.push_back(FilePath + "mipsel-nacl/usr/lib"); prog_paths.push_back(ProgPath + "bin"); file_paths.push_back(ToolPath + "mipsel-nacl"); break; default: break; } NaClArmMacrosPath = GetFilePath("nacl-arm-macros.s"); }
static StringRef getOSLibDir(const llvm::Triple &Triple, const ArgList &Args) { if (tools::isMipsArch(Triple.getArch())) { if (Triple.isAndroid()) { StringRef CPUName; StringRef ABIName; tools::mips::getMipsCPUAndABI(Args, Triple, CPUName, ABIName); if (CPUName == "mips32r6") return "libr6"; if (CPUName == "mips32r2") return "libr2"; } // lib32 directory has a special meaning on MIPS targets. // It contains N32 ABI binaries. Use this folder if produce // code for N32 ABI only. if (tools::mips::hasMipsAbiArg(Args, "n32")) return "lib32"; return Triple.isArch32Bit() ? "lib" : "lib64"; } // It happens that only x86 and PPC use the 'lib32' variant of oslibdir, and // using that variant while targeting other architectures causes problems // because the libraries are laid out in shared system roots that can't cope // with a 'lib32' library search path being considered. So we only enable // them when we know we may need it. // // FIXME: This is a bit of a hack. We should really unify this code for // reasoning about oslibdir spellings with the lib dir spellings in the // GCCInstallationDetector, but that is a more significant refactoring. if (Triple.getArch() == llvm::Triple::x86 || Triple.getArch() == llvm::Triple::ppc) return "lib32"; if (Triple.getArch() == llvm::Triple::x86_64 && Triple.getEnvironment() == llvm::Triple::GNUX32) return "libx32"; return Triple.isArch32Bit() ? "lib" : "lib64"; }
NetBSD::NetBSD(const Driver &D, const llvm::Triple &Triple, const ArgList &Args) : Generic_ELF(D, Triple, Args) { if (getDriver().UseStdLib) { // When targeting a 32-bit platform, try the special directory used on // 64-bit hosts, and only fall back to the main library directory if that // doesn't work. // FIXME: It'd be nicer to test if this directory exists, but I'm not sure // what all logic is needed to emulate the '=' prefix here. switch (Triple.getArch()) { case llvm::Triple::x86: getFilePaths().push_back("=/usr/lib/i386"); break; case llvm::Triple::arm: case llvm::Triple::armeb: case llvm::Triple::thumb: case llvm::Triple::thumbeb: switch (Triple.getEnvironment()) { case llvm::Triple::EABI: case llvm::Triple::GNUEABI: getFilePaths().push_back("=/usr/lib/eabi"); break; case llvm::Triple::EABIHF: case llvm::Triple::GNUEABIHF: getFilePaths().push_back("=/usr/lib/eabihf"); break; default: getFilePaths().push_back("=/usr/lib/oabi"); break; } break; case llvm::Triple::mips64: case llvm::Triple::mips64el: if (tools::mips::hasMipsAbiArg(Args, "o32")) getFilePaths().push_back("=/usr/lib/o32"); else if (tools::mips::hasMipsAbiArg(Args, "64")) getFilePaths().push_back("=/usr/lib/64"); break; case llvm::Triple::ppc: getFilePaths().push_back("=/usr/lib/powerpc"); break; case llvm::Triple::sparc: getFilePaths().push_back("=/usr/lib/sparc"); break; default: break; } getFilePaths().push_back("=/usr/lib"); } }
static StringRef getSolarisLibSuffix(const llvm::Triple &Triple) { switch (Triple.getArch()) { case llvm::Triple::x86: case llvm::Triple::sparc: break; case llvm::Triple::x86_64: return "/amd64"; case llvm::Triple::sparcv9: return "/sparcv9"; default: llvm_unreachable("Unsupported architecture"); } return ""; }
static std::unique_ptr<TargetHandler> createTarget(llvm::Triple triple, MipsLinkingContext &ctx) { switch (triple.getArch()) { case llvm::Triple::mips: return llvm::make_unique<MipsTargetHandler<ELF32BE>>(ctx); case llvm::Triple::mipsel: return llvm::make_unique<MipsTargetHandler<ELF32LE>>(ctx); case llvm::Triple::mips64: return llvm::make_unique<MipsTargetHandler<ELF64BE>>(ctx); case llvm::Triple::mips64el: return llvm::make_unique<MipsTargetHandler<ELF64LE>>(ctx); default: llvm_unreachable("Unhandled arch"); } }
static std::string getX86TargetCPU(std::string arch, const llvm::Triple &triple) { if (!arch.empty()) { if (arch != "native") return arch; // FIXME: Reject attempts to use -march=native unless the target matches // the host. // // FIXME: We should also incorporate the detected target features for use // with -native. std::string cpu = llvm::sys::getHostCPUName(); if (!cpu.empty() && cpu != "generic") return cpu; } // Select the default CPU if none was given (or detection failed). bool is64Bit = triple.getArch() == llvm::Triple::x86_64; if (triple.isOSDarwin()) return is64Bit ? "core2" : "yonah"; // Everything else goes to x86-64 in 64-bit mode. if (is64Bit) return "x86-64"; if (triple.getOSName().startswith("haiku")) return "i586"; if (triple.getOSName().startswith("openbsd")) return "i486"; if (triple.getOSName().startswith("bitrig")) return "i686"; if (triple.getOSName().startswith("freebsd")) return "i486"; if (triple.getOSName().startswith("netbsd")) return "i486"; #if LDC_LLVM_VER >= 302 // All x86 devices running Android have core2 as their common // denominator. This makes a better choice than pentium4. if (triple.getEnvironment() == llvm::Triple::Android) return "core2"; #endif // Fallback to p4. return "pentium4"; }
/// Is the triple {arm,thumb}-none-none-{eabi,eabihf} ? static bool isARMBareMetal(const llvm::Triple &Triple) { if (Triple.getArch() != llvm::Triple::arm && Triple.getArch() != llvm::Triple::thumb) return false; if (Triple.getVendor() != llvm::Triple::UnknownVendor) return false; if (Triple.getOS() != llvm::Triple::UnknownOS) return false; if (Triple.getEnvironment() != llvm::Triple::EABI && Triple.getEnvironment() != llvm::Triple::EABIHF) return false; return true; }
static std::string getCPU(llvm::Triple const &triple) { switch (triple.getArch()) { case llvm::Triple::arm : case llvm::Triple::thumb : return "arm"; case llvm::Triple::ppc : case llvm::Triple::ppc64 : return "ppc"; case llvm::Triple::sparc : case llvm::Triple::sparcv9 : return "sparc"; case llvm::Triple::x86 : case llvm::Triple::x86_64 : return "x86"; default : return triple.getArchName().str(); } }
void InitHeaderSearch::AddGnuCPlusPlusIncludePaths(StringRef Base, StringRef ArchDir, StringRef Dir32, StringRef Dir64, const llvm::Triple &triple) { // Add the base dir AddPath(Base, CXXSystem, false); // Add the multilib dirs llvm::Triple::ArchType arch = triple.getArch(); bool is64bit = arch == llvm::Triple::ppc64 || arch == llvm::Triple::x86_64; if (is64bit) AddPath(Base + "/" + ArchDir + "/" + Dir64, CXXSystem, false); else AddPath(Base + "/" + ArchDir + "/" + Dir32, CXXSystem, false); // Add the backward dir AddPath(Base + "/backward", CXXSystem, false); }
FreeBSD::FreeBSD(const HostInfo &Host, const llvm::Triple& Triple) : Generic_GCC(Host, Triple) { // Determine if we are compiling 32-bit code on an x86_64 platform. bool Lib32 = false; if (Triple.getArch() == llvm::Triple::x86 && llvm::Triple(getDriver().DefaultHostTriple).getArch() == llvm::Triple::x86_64) Lib32 = true; getProgramPaths().push_back(getDriver().Dir + "/../libexec"); getProgramPaths().push_back("/usr/libexec"); if (Lib32) { getFilePaths().push_back(getDriver().Dir + "/../lib32"); getFilePaths().push_back("/usr/lib32"); } else { getFilePaths().push_back(getDriver().Dir + "/../lib"); getFilePaths().push_back("/usr/lib"); } }
std::unique_ptr<ELFLinkingContext> ELFLinkingContext::create(llvm::Triple triple) { switch (triple.getArch()) { case llvm::Triple::x86: return std::unique_ptr<ELFLinkingContext>( new lld::elf::X86LinkingContext(triple)); case llvm::Triple::x86_64: return std::unique_ptr<ELFLinkingContext>( new lld::elf::X86_64LinkingContext(triple)); case llvm::Triple::hexagon: return std::unique_ptr<ELFLinkingContext>( new lld::elf::HexagonLinkingContext(triple)); case llvm::Triple::mipsel: return std::unique_ptr<ELFLinkingContext>( new lld::elf::MipsLinkingContext(triple)); case llvm::Triple::ppc: return std::unique_ptr<ELFLinkingContext>( new lld::elf::PPCLinkingContext(triple)); default: return nullptr; } }
bool Driver::ShouldUseClangCompiler(const Compilation &C, const JobAction &JA, const llvm::Triple &Triple) const { // Check if user requested no clang, or clang doesn't understand this type (we // only handle single inputs for now). if (!CCCUseClang || JA.size() != 1 || !types::isAcceptedByClang((*JA.begin())->getType())) return false; // Otherwise make sure this is an action clang understands. if (isa<PreprocessJobAction>(JA)) { if (!CCCUseClangCPP) { Diag(clang::diag::warn_drv_not_using_clang_cpp); return false; } } else if (!isa<PrecompileJobAction>(JA) && !isa<CompileJobAction>(JA)) return false; // Use clang for C++? if (!CCCUseClangCXX && types::isCXX((*JA.begin())->getType())) { Diag(clang::diag::warn_drv_not_using_clang_cxx); return false; } // Always use clang for precompiling, AST generation, and rewriting, // regardless of archs. if (isa<PrecompileJobAction>(JA) || JA.getType() == types::TY_AST || JA.getType() == types::TY_RewrittenObjC) return true; // Finally, don't use clang if this isn't one of the user specified archs to // build. if (!CCCClangArchs.empty() && !CCCClangArchs.count(Triple.getArch())) { Diag(clang::diag::warn_drv_not_using_clang_arch) << Triple.getArchName(); return false; } return true; }
std::string getTargetCPU(const std::string& specifiedCPU, const llvm::Triple& triple) { if (!specifiedCPU.empty()) { if (specifiedCPU == "native") { // Try to get the host CPU name. const std::string hostCPU = llvm::sys::getHostCPUName(); if (!hostCPU.empty() && hostCPU != "generic") { return hostCPU; } } else { return specifiedCPU; } } switch (triple.getArch()) { case llvm::Triple::x86: case llvm::Triple::x86_64: return getX86TargetCPU(triple); case llvm::Triple::arm: return getARMTargetCPU(triple); default: // Unknown platform, so just pass to LLVM and let it decide. return specifiedCPU; } }
void InitHeaderSearch:: AddDefaultCPlusPlusIncludePaths(const llvm::Triple &triple, const HeaderSearchOptions &HSOpts) { llvm::Triple::OSType os = triple.getOS(); // FIXME: temporary hack: hard-coded paths. if (triple.isOSDarwin()) { switch (triple.getArch()) { default: break; case llvm::Triple::ppc: case llvm::Triple::ppc64: AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.2.1", "powerpc-apple-darwin10", "", "ppc64", triple); AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.0.0", "powerpc-apple-darwin10", "", "ppc64", triple); break; case llvm::Triple::x86: case llvm::Triple::x86_64: AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.2.1", "i686-apple-darwin10", "", "x86_64", triple); AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.0.0", "i686-apple-darwin8", "", "", triple); break; case llvm::Triple::arm: case llvm::Triple::thumb: AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.2.1", "arm-apple-darwin10", "v7", "", triple); AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.2.1", "arm-apple-darwin10", "v6", "", triple); break; case llvm::Triple::aarch64: case llvm::Triple::arm64: AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.2.1", "arm64-apple-darwin10", "", "", triple); break; } return; } switch (os) { case llvm::Triple::Linux: llvm_unreachable("Include management is handled in the driver."); case llvm::Triple::Win32: switch (triple.getEnvironment()) { default: llvm_unreachable("Include management is handled in the driver."); case llvm::Triple::Cygnus: // Cygwin-1.7 AddMinGWCPlusPlusIncludePaths("/usr/lib/gcc", "i686-pc-cygwin", "4.7.3"); AddMinGWCPlusPlusIncludePaths("/usr/lib/gcc", "i686-pc-cygwin", "4.5.3"); AddMinGWCPlusPlusIncludePaths("/usr/lib/gcc", "i686-pc-cygwin", "4.3.4"); // g++-4 / Cygwin-1.5 AddMinGWCPlusPlusIncludePaths("/usr/lib/gcc", "i686-pc-cygwin", "4.3.2"); break; case llvm::Triple::GNU: // mingw-w64 C++ include paths (i686-w64-mingw32 and x86_64-w64-mingw32) AddMinGW64CXXPaths(HSOpts.ResourceDir, "4.7.0"); AddMinGW64CXXPaths(HSOpts.ResourceDir, "4.7.1"); AddMinGW64CXXPaths(HSOpts.ResourceDir, "4.7.2"); AddMinGW64CXXPaths(HSOpts.ResourceDir, "4.7.3"); AddMinGW64CXXPaths(HSOpts.ResourceDir, "4.8.0"); AddMinGW64CXXPaths(HSOpts.ResourceDir, "4.8.1"); AddMinGW64CXXPaths(HSOpts.ResourceDir, "4.8.2"); // mingw.org C++ include paths #if defined(LLVM_ON_WIN32) AddMinGWCPlusPlusIncludePaths("c:/MinGW/lib/gcc", "mingw32", "4.7.0"); AddMinGWCPlusPlusIncludePaths("c:/MinGW/lib/gcc", "mingw32", "4.7.1"); AddMinGWCPlusPlusIncludePaths("c:/MinGW/lib/gcc", "mingw32", "4.7.2"); AddMinGWCPlusPlusIncludePaths("c:/MinGW/lib/gcc", "mingw32", "4.7.3"); AddMinGWCPlusPlusIncludePaths("c:/MinGW/lib/gcc", "mingw32", "4.8.0"); AddMinGWCPlusPlusIncludePaths("c:/MinGW/lib/gcc", "mingw32", "4.8.1"); AddMinGWCPlusPlusIncludePaths("c:/MinGW/lib/gcc", "mingw32", "4.8.2"); #endif break; } case llvm::Triple::DragonFly: if (llvm::sys::fs::exists("/usr/lib/gcc47")) AddPath("/usr/include/c++/4.7", CXXSystem, false); else AddPath("/usr/include/c++/4.4", CXXSystem, false); break; case llvm::Triple::OpenBSD: { std::string t = triple.getTriple(); if (t.substr(0, 6) == "x86_64") t.replace(0, 6, "amd64"); AddGnuCPlusPlusIncludePaths("/usr/include/g++", t, "", "", triple); break; } case llvm::Triple::Minix: AddGnuCPlusPlusIncludePaths("/usr/gnu/include/c++/4.4.3", "", "", "", triple); break; case llvm::Triple::Solaris: AddGnuCPlusPlusIncludePaths("/usr/gcc/4.5/include/c++/4.5.2/", "i386-pc-solaris2.11", "", "", triple); // Solaris - Fall though.. case llvm::Triple::AuroraUX: // AuroraUX AddGnuCPlusPlusIncludePaths("/opt/gcc4/include/c++/4.2.4", "i386-pc-solaris2.11", "", "", triple); break; default: break; } }
bool swift::tripleIsWatchSimulator(const llvm::Triple &triple) { llvm::Triple::ArchType arch = triple.getArch(); return (triple.isWatchOS() && (arch == llvm::Triple::x86 || arch == llvm::Triple::x86_64)); }
/// \brief Get our best guess at the multiarch triple for a target. /// /// Debian-based systems are starting to use a multiarch setup where they use /// a target-triple directory in the library and header search paths. /// Unfortunately, this triple does not align with the vanilla target triple, /// so we provide a rough mapping here. static std::string getMultiarchTriple(const Driver &D, const llvm::Triple &TargetTriple, StringRef SysRoot) { llvm::Triple::EnvironmentType TargetEnvironment = TargetTriple.getEnvironment(); // For most architectures, just use whatever we have rather than trying to be // clever. switch (TargetTriple.getArch()) { default: break; // We use the existence of '/lib/<triple>' as a directory to detect some // common linux triples that don't quite match the Clang triple for both // 32-bit and 64-bit targets. Multiarch fixes its install triples to these // regardless of what the actual target triple is. case llvm::Triple::arm: case llvm::Triple::thumb: if (TargetEnvironment == llvm::Triple::GNUEABIHF) { if (D.getVFS().exists(SysRoot + "/lib/arm-linux-gnueabihf")) return "arm-linux-gnueabihf"; } else { if (D.getVFS().exists(SysRoot + "/lib/arm-linux-gnueabi")) return "arm-linux-gnueabi"; } break; case llvm::Triple::armeb: case llvm::Triple::thumbeb: if (TargetEnvironment == llvm::Triple::GNUEABIHF) { if (D.getVFS().exists(SysRoot + "/lib/armeb-linux-gnueabihf")) return "armeb-linux-gnueabihf"; } else { if (D.getVFS().exists(SysRoot + "/lib/armeb-linux-gnueabi")) return "armeb-linux-gnueabi"; } break; case llvm::Triple::x86: if (D.getVFS().exists(SysRoot + "/lib/i386-linux-gnu")) return "i386-linux-gnu"; break; case llvm::Triple::x86_64: // We don't want this for x32, otherwise it will match x86_64 libs if (TargetEnvironment != llvm::Triple::GNUX32 && D.getVFS().exists(SysRoot + "/lib/x86_64-linux-gnu")) return "x86_64-linux-gnu"; break; case llvm::Triple::aarch64: if (D.getVFS().exists(SysRoot + "/lib/aarch64-linux-gnu")) return "aarch64-linux-gnu"; break; case llvm::Triple::aarch64_be: if (D.getVFS().exists(SysRoot + "/lib/aarch64_be-linux-gnu")) return "aarch64_be-linux-gnu"; break; case llvm::Triple::mips: if (D.getVFS().exists(SysRoot + "/lib/mips-linux-gnu")) return "mips-linux-gnu"; break; case llvm::Triple::mipsel: if (D.getVFS().exists(SysRoot + "/lib/mipsel-linux-gnu")) return "mipsel-linux-gnu"; break; case llvm::Triple::mips64: if (D.getVFS().exists(SysRoot + "/lib/mips64-linux-gnu")) return "mips64-linux-gnu"; if (D.getVFS().exists(SysRoot + "/lib/mips64-linux-gnuabi64")) return "mips64-linux-gnuabi64"; break; case llvm::Triple::mips64el: if (D.getVFS().exists(SysRoot + "/lib/mips64el-linux-gnu")) return "mips64el-linux-gnu"; if (D.getVFS().exists(SysRoot + "/lib/mips64el-linux-gnuabi64")) return "mips64el-linux-gnuabi64"; break; case llvm::Triple::ppc: if (D.getVFS().exists(SysRoot + "/lib/powerpc-linux-gnuspe")) return "powerpc-linux-gnuspe"; if (D.getVFS().exists(SysRoot + "/lib/powerpc-linux-gnu")) return "powerpc-linux-gnu"; break; case llvm::Triple::ppc64: if (D.getVFS().exists(SysRoot + "/lib/powerpc64-linux-gnu")) return "powerpc64-linux-gnu"; break; case llvm::Triple::ppc64le: if (D.getVFS().exists(SysRoot + "/lib/powerpc64le-linux-gnu")) return "powerpc64le-linux-gnu"; break; case llvm::Triple::sparc: if (D.getVFS().exists(SysRoot + "/lib/sparc-linux-gnu")) return "sparc-linux-gnu"; break; case llvm::Triple::sparcv9: if (D.getVFS().exists(SysRoot + "/lib/sparc64-linux-gnu")) return "sparc64-linux-gnu"; break; case llvm::Triple::systemz: if (D.getVFS().exists(SysRoot + "/lib/s390x-linux-gnu")) return "s390x-linux-gnu"; break; } return TargetTriple.str(); }
Linux::Linux(const Driver &D, const llvm::Triple &Triple, const ArgList &Args) : Generic_ELF(D, Triple, Args) { GCCInstallation.init(Triple, Args); Multilibs = GCCInstallation.getMultilibs(); llvm::Triple::ArchType Arch = Triple.getArch(); std::string SysRoot = computeSysRoot(); // Cross-compiling binutils and GCC installations (vanilla and openSUSE at // least) put various tools in a triple-prefixed directory off of the parent // of the GCC installation. We use the GCC triple here to ensure that we end // up with tools that support the same amount of cross compiling as the // detected GCC installation. For example, if we find a GCC installation // targeting x86_64, but it is a bi-arch GCC installation, it can also be // used to target i386. // FIXME: This seems unlikely to be Linux-specific. ToolChain::path_list &PPaths = getProgramPaths(); PPaths.push_back(Twine(GCCInstallation.getParentLibPath() + "/../" + GCCInstallation.getTriple().str() + "/bin") .str()); Distro Distro(D.getVFS()); if (Distro.IsOpenSUSE() || Distro.IsUbuntu()) { ExtraOpts.push_back("-z"); ExtraOpts.push_back("relro"); } if (Arch == llvm::Triple::arm || Arch == llvm::Triple::thumb) ExtraOpts.push_back("-X"); const bool IsAndroid = Triple.isAndroid(); const bool IsMips = tools::isMipsArch(Arch); const bool IsHexagon = Arch == llvm::Triple::hexagon; if (IsMips && !SysRoot.empty()) ExtraOpts.push_back("--sysroot=" + SysRoot); // Do not use 'gnu' hash style for Mips targets because .gnu.hash // and the MIPS ABI require .dynsym to be sorted in different ways. // .gnu.hash needs symbols to be grouped by hash code whereas the MIPS // ABI requires a mapping between the GOT and the symbol table. // Android loader does not support .gnu.hash. // Hexagon linker/loader does not support .gnu.hash if (!IsMips && !IsAndroid && !IsHexagon) { if (Distro.IsRedhat() || Distro.IsOpenSUSE() || (Distro.IsUbuntu() && Distro >= Distro::UbuntuMaverick)) ExtraOpts.push_back("--hash-style=gnu"); if (Distro.IsDebian() || Distro.IsOpenSUSE() || Distro == Distro::UbuntuLucid || Distro == Distro::UbuntuJaunty || Distro == Distro::UbuntuKarmic) ExtraOpts.push_back("--hash-style=both"); } if (Distro.IsRedhat() && Distro != Distro::RHEL5 && Distro != Distro::RHEL6) ExtraOpts.push_back("--no-add-needed"); #ifdef ENABLE_LINKER_BUILD_ID ExtraOpts.push_back("--build-id"); #endif if (Distro.IsOpenSUSE()) ExtraOpts.push_back("--enable-new-dtags"); // The selection of paths to try here is designed to match the patterns which // the GCC driver itself uses, as this is part of the GCC-compatible driver. // This was determined by running GCC in a fake filesystem, creating all // possible permutations of these directories, and seeing which ones it added // to the link paths. path_list &Paths = getFilePaths(); const std::string OSLibDir = getOSLibDir(Triple, Args); const std::string MultiarchTriple = getMultiarchTriple(D, Triple, SysRoot); // Add the multilib suffixed paths where they are available. if (GCCInstallation.isValid()) { const llvm::Triple &GCCTriple = GCCInstallation.getTriple(); const std::string &LibPath = GCCInstallation.getParentLibPath(); const Multilib &Multilib = GCCInstallation.getMultilib(); const MultilibSet &Multilibs = GCCInstallation.getMultilibs(); // Add toolchain / multilib specific file paths. addMultilibsFilePaths(D, Multilibs, Multilib, GCCInstallation.getInstallPath(), Paths); // Sourcery CodeBench MIPS toolchain holds some libraries under // a biarch-like suffix of the GCC installation. addPathIfExists(D, GCCInstallation.getInstallPath() + Multilib.gccSuffix(), Paths); // GCC cross compiling toolchains will install target libraries which ship // as part of the toolchain under <prefix>/<triple>/<libdir> rather than as // any part of the GCC installation in // <prefix>/<libdir>/gcc/<triple>/<version>. This decision is somewhat // debatable, but is the reality today. We need to search this tree even // when we have a sysroot somewhere else. It is the responsibility of // whomever is doing the cross build targeting a sysroot using a GCC // installation that is *not* within the system root to ensure two things: // // 1) Any DSOs that are linked in from this tree or from the install path // above must be present on the system root and found via an // appropriate rpath. // 2) There must not be libraries installed into // <prefix>/<triple>/<libdir> unless they should be preferred over // those within the system root. // // Note that this matches the GCC behavior. See the below comment for where // Clang diverges from GCC's behavior. addPathIfExists(D, LibPath + "/../" + GCCTriple.str() + "/lib/../" + OSLibDir + Multilib.osSuffix(), Paths); // If the GCC installation we found is inside of the sysroot, we want to // prefer libraries installed in the parent prefix of the GCC installation. // It is important to *not* use these paths when the GCC installation is // outside of the system root as that can pick up unintended libraries. // This usually happens when there is an external cross compiler on the // host system, and a more minimal sysroot available that is the target of // the cross. Note that GCC does include some of these directories in some // configurations but this seems somewhere between questionable and simply // a bug. if (StringRef(LibPath).startswith(SysRoot)) { addPathIfExists(D, LibPath + "/" + MultiarchTriple, Paths); addPathIfExists(D, LibPath + "/../" + OSLibDir, Paths); } } // Similar to the logic for GCC above, if we currently running Clang inside // of the requested system root, add its parent library paths to // those searched. // FIXME: It's not clear whether we should use the driver's installed // directory ('Dir' below) or the ResourceDir. if (StringRef(D.Dir).startswith(SysRoot)) { addPathIfExists(D, D.Dir + "/../lib/" + MultiarchTriple, Paths); addPathIfExists(D, D.Dir + "/../" + OSLibDir, Paths); } addPathIfExists(D, SysRoot + "/lib/" + MultiarchTriple, Paths); addPathIfExists(D, SysRoot + "/lib/../" + OSLibDir, Paths); addPathIfExists(D, SysRoot + "/usr/lib/" + MultiarchTriple, Paths); addPathIfExists(D, SysRoot + "/usr/lib/../" + OSLibDir, Paths); // Try walking via the GCC triple path in case of biarch or multiarch GCC // installations with strange symlinks. if (GCCInstallation.isValid()) { addPathIfExists(D, SysRoot + "/usr/lib/" + GCCInstallation.getTriple().str() + "/../../" + OSLibDir, Paths); // Add the 'other' biarch variant path Multilib BiarchSibling; if (GCCInstallation.getBiarchSibling(BiarchSibling)) { addPathIfExists(D, GCCInstallation.getInstallPath() + BiarchSibling.gccSuffix(), Paths); } // See comments above on the multilib variant for details of why this is // included even from outside the sysroot. const std::string &LibPath = GCCInstallation.getParentLibPath(); const llvm::Triple &GCCTriple = GCCInstallation.getTriple(); const Multilib &Multilib = GCCInstallation.getMultilib(); addPathIfExists(D, LibPath + "/../" + GCCTriple.str() + "/lib" + Multilib.osSuffix(), Paths); // See comments above on the multilib variant for details of why this is // only included from within the sysroot. if (StringRef(LibPath).startswith(SysRoot)) addPathIfExists(D, LibPath, Paths); } // Similar to the logic for GCC above, if we are currently running Clang // inside of the requested system root, add its parent library path to those // searched. // FIXME: It's not clear whether we should use the driver's installed // directory ('Dir' below) or the ResourceDir. if (StringRef(D.Dir).startswith(SysRoot)) addPathIfExists(D, D.Dir + "/../lib", Paths); addPathIfExists(D, SysRoot + "/lib", Paths); addPathIfExists(D, SysRoot + "/usr/lib", Paths); }