diff options
Diffstat (limited to 'contrib/llvm/tools/clang/lib/Driver/ToolChains.cpp')
-rw-r--r-- | contrib/llvm/tools/clang/lib/Driver/ToolChains.cpp | 205 |
1 files changed, 143 insertions, 62 deletions
diff --git a/contrib/llvm/tools/clang/lib/Driver/ToolChains.cpp b/contrib/llvm/tools/clang/lib/Driver/ToolChains.cpp index 499587a..2f7bd75 100644 --- a/contrib/llvm/tools/clang/lib/Driver/ToolChains.cpp +++ b/contrib/llvm/tools/clang/lib/Driver/ToolChains.cpp @@ -9,6 +9,10 @@ #include "ToolChains.h" +#ifdef HAVE_CLANG_CONFIG_H +# include "clang/Config/config.h" +#endif + #include "clang/Driver/Arg.h" #include "clang/Driver/ArgList.h" #include "clang/Driver/Compilation.h" @@ -119,7 +123,7 @@ llvm::StringRef Darwin::getDarwinArchName(const ArgList &Args) const { switch (getTriple().getArch()) { default: return getArchName(); - + case llvm::Triple::thumb: case llvm::Triple::arm: { if (const Arg *A = Args.getLastArg(options::OPT_march_EQ)) @@ -149,10 +153,10 @@ std::string Darwin::ComputeEffectiveClangTriple(const ArgList &Args) const { // the default triple). if (!isTargetInitialized()) return Triple.getTriple(); - + unsigned Version[3]; getTargetVersion(Version); - + llvm::SmallString<16> Str; llvm::raw_svector_ostream(Str) << (isTargetIPhoneOS() ? "ios" : "macosx") @@ -562,7 +566,7 @@ void DarwinClang::AddCCKextLibArgs(const ArgList &Args, P.appendComponent("lib"); P.appendComponent("darwin"); P.appendComponent("libclang_rt.cc_kext.a"); - + // For now, allow missing resource libraries to support developers who may // not have compiler-rt checked out or integrated into their build. bool Exists; @@ -628,7 +632,7 @@ DerivedArgList *Darwin::TranslateArgs(const DerivedArgList &Args, DAL->AddSeparateArg(OriginalArg, Opts.getOption(options::OPT_Zlinker_input), A->getValue(Args, i)); - + } continue; } @@ -919,8 +923,8 @@ TCEToolChain::~TCEToolChain() { delete it->second; } -bool TCEToolChain::IsMathErrnoDefault() const { - return true; +bool TCEToolChain::IsMathErrnoDefault() const { + return true; } bool TCEToolChain::IsUnwindTablesDefault() const { @@ -935,7 +939,7 @@ const char *TCEToolChain::GetForcedPicModel() const { return 0; } -Tool &TCEToolChain::SelectTool(const Compilation &C, +Tool &TCEToolChain::SelectTool(const Compilation &C, const JobAction &JA, const ActionList &Inputs) const { Action::ActionClass Key; @@ -1006,7 +1010,12 @@ FreeBSD::FreeBSD(const HostInfo &Host, const llvm::Triple& Triple) llvm::Triple(getDriver().DefaultHostTriple).getArch() == llvm::Triple::x86_64) Lib32 = true; - + + if (Triple.getArch() == llvm::Triple::ppc && + llvm::Triple(getDriver().DefaultHostTriple).getArch() == + llvm::Triple::ppc64) + Lib32 = true; + if (Lib32) { getFilePaths().push_back(CLANG_PREFIX "/usr/lib32"); } else { @@ -1047,14 +1056,14 @@ Tool &FreeBSD::SelectTool(const Compilation &C, const JobAction &JA, /// NetBSD - NetBSD tool chain which can call as(1) and ld(1) directly. -NetBSD::NetBSD(const HostInfo &Host, const llvm::Triple& Triple) - : Generic_ELF(Host, Triple) { +NetBSD::NetBSD(const HostInfo &Host, const llvm::Triple& Triple, + const llvm::Triple& ToolTriple) + : Generic_ELF(Host, Triple), ToolTriple(ToolTriple) { // 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) + if (ToolTriple.getArch() == llvm::Triple::x86_64 && + Triple.getArch() == llvm::Triple::x86) Lib32 = true; if (getDriver().UseStdLib) { @@ -1084,10 +1093,11 @@ Tool &NetBSD::SelectTool(const Compilation &C, const JobAction &JA, if (UseIntegratedAs) T = new tools::ClangAs(*this); else - T = new tools::netbsd::Assemble(*this); + T = new tools::netbsd::Assemble(*this, ToolTriple); break; case Action::LinkJobClass: - T = new tools::netbsd::Link(*this); break; + T = new tools::netbsd::Link(*this, ToolTriple); + break; default: T = &Generic_GCC::SelectTool(C, JA, Inputs); } @@ -1176,12 +1186,18 @@ enum LinuxDistro { ArchLinux, DebianLenny, DebianSqueeze, + DebianWheezy, Exherbo, + RHEL4, + RHEL5, + RHEL6, Fedora13, Fedora14, Fedora15, FedoraRawhide, OpenSuse11_3, + OpenSuse11_4, + OpenSuse12_1, UbuntuHardy, UbuntuIntrepid, UbuntuJaunty, @@ -1189,27 +1205,31 @@ enum LinuxDistro { UbuntuLucid, UbuntuMaverick, UbuntuNatty, + UbuntuOneiric, UnknownDistro }; -static bool IsFedora(enum LinuxDistro Distro) { +static bool IsRedhat(enum LinuxDistro Distro) { return Distro == Fedora13 || Distro == Fedora14 || - Distro == Fedora15 || Distro == FedoraRawhide; + Distro == Fedora15 || Distro == FedoraRawhide || + Distro == RHEL4 || Distro == RHEL5 || Distro == RHEL6; } static bool IsOpenSuse(enum LinuxDistro Distro) { - return Distro == OpenSuse11_3; + return Distro == OpenSuse11_3 || Distro == OpenSuse11_4 || + Distro == OpenSuse12_1; } static bool IsDebian(enum LinuxDistro Distro) { - return Distro == DebianLenny || Distro == DebianSqueeze; + return Distro == DebianLenny || Distro == DebianSqueeze || + Distro == DebianWheezy; } static bool IsUbuntu(enum LinuxDistro Distro) { return Distro == UbuntuHardy || Distro == UbuntuIntrepid || - Distro == UbuntuLucid || Distro == UbuntuMaverick || + Distro == UbuntuLucid || Distro == UbuntuMaverick || Distro == UbuntuJaunty || Distro == UbuntuKarmic || - Distro == UbuntuNatty; + Distro == UbuntuNatty || Distro == UbuntuOneiric; } static bool IsDebianBased(enum LinuxDistro Distro) { @@ -1227,7 +1247,8 @@ static bool HasMultilib(llvm::Triple::ArchType Arch, enum LinuxDistro Distro) { } if (Arch == llvm::Triple::ppc64) return true; - if ((Arch == llvm::Triple::x86 || Arch == llvm::Triple::ppc) && IsDebianBased(Distro)) + if ((Arch == llvm::Triple::x86 || Arch == llvm::Triple::ppc) && + IsDebianBased(Distro)) return true; return false; } @@ -1253,6 +1274,8 @@ static LinuxDistro DetectLinuxDistro(llvm::Triple::ArchType Arch) { return UbuntuMaverick; else if (Lines[i] == "DISTRIB_CODENAME=natty") return UbuntuNatty; + else if (Lines[i] == "DISTRIB_CODENAME=oneiric") + return UbuntuOneiric; } return UnknownDistro; } @@ -1268,6 +1291,17 @@ static LinuxDistro DetectLinuxDistro(llvm::Triple::ArchType Arch) { else if (Data.startswith("Fedora release") && Data.find("Rawhide") != llvm::StringRef::npos) return FedoraRawhide; + else if (Data.startswith("Red Hat Enterprise Linux") && + Data.find("release 6") != llvm::StringRef::npos) + return RHEL6; + else if ((Data.startswith("Red Hat Enterprise Linux") || + Data.startswith("CentOS")) && + Data.find("release 5") != llvm::StringRef::npos) + return RHEL5; + else if ((Data.startswith("Red Hat Enterprise Linux") || + Data.startswith("CentOS")) && + Data.find("release 4") != llvm::StringRef::npos) + return RHEL4; return UnknownDistro; } @@ -1277,6 +1311,8 @@ static LinuxDistro DetectLinuxDistro(llvm::Triple::ArchType Arch) { return DebianLenny; else if (Data.startswith("squeeze/sid")) return DebianSqueeze; + else if (Data.startswith("wheezy/sid")) + return DebianWheezy; return UnknownDistro; } @@ -1284,6 +1320,10 @@ static LinuxDistro DetectLinuxDistro(llvm::Triple::ArchType Arch) { llvm::StringRef Data = File.get()->getBuffer(); if (Data.startswith("openSUSE 11.3")) return OpenSuse11_3; + else if (Data.startswith("openSUSE 11.4")) + return OpenSuse11_4; + else if (Data.startswith("openSUSE 12.1")) + return OpenSuse12_1; return UnknownDistro; } @@ -1297,6 +1337,54 @@ static LinuxDistro DetectLinuxDistro(llvm::Triple::ArchType Arch) { return UnknownDistro; } +static std::string findGCCBaseLibDir(const std::string &GccTriple) { + // FIXME: Using CXX_INCLUDE_ROOT is here is a bit of a hack, but + // avoids adding yet another option to configure/cmake. + // It would probably be cleaner to break it in two variables + // CXX_GCC_ROOT with just /foo/bar + // CXX_GCC_VER with 4.5.2 + // Then we would have + // CXX_INCLUDE_ROOT = CXX_GCC_ROOT/include/c++/CXX_GCC_VER + // and this function would return + // CXX_GCC_ROOT/lib/gcc/CXX_INCLUDE_ARCH/CXX_GCC_VER + llvm::SmallString<128> CxxIncludeRoot(CXX_INCLUDE_ROOT); + if (CxxIncludeRoot != "") { + // This is of the form /foo/bar/include/c++/4.5.2/ + if (CxxIncludeRoot.back() == '/') + llvm::sys::path::remove_filename(CxxIncludeRoot); // remove the / + llvm::StringRef Version = llvm::sys::path::filename(CxxIncludeRoot); + llvm::sys::path::remove_filename(CxxIncludeRoot); // remove the version + llvm::sys::path::remove_filename(CxxIncludeRoot); // remove the c++ + llvm::sys::path::remove_filename(CxxIncludeRoot); // remove the include + std::string ret(CxxIncludeRoot.c_str()); + ret.append("/lib/gcc/"); + ret.append(CXX_INCLUDE_ARCH); + ret.append("/"); + ret.append(Version); + return ret; + } + static const char* GccVersions[] = {"4.6.0", "4.6", + "4.5.2", "4.5.1", "4.5", + "4.4.5", "4.4.4", "4.4.3", "4.4", + "4.3.4", "4.3.3", "4.3.2", "4.3", + "4.2.4", "4.2.3", "4.2.2", "4.2.1", + "4.2", "4.1.1"}; + bool Exists; + for (unsigned i = 0; i < sizeof(GccVersions)/sizeof(char*); ++i) { + std::string Suffix = GccTriple + "/" + GccVersions[i]; + std::string t1 = "/usr/lib/gcc/" + Suffix; + if (!llvm::sys::fs::exists(t1 + "/crtbegin.o", Exists) && Exists) + return t1; + std::string t2 = "/usr/lib64/gcc/" + Suffix; + if (!llvm::sys::fs::exists(t2 + "/crtbegin.o", Exists) && Exists) + return t2; + std::string t3 = "/usr/lib/" + GccTriple + "/gcc/" + Suffix; + if (!llvm::sys::fs::exists(t3 + "/crtbegin.o", Exists) && Exists) + return t3; + } + return ""; +} + Linux::Linux(const HostInfo &Host, const llvm::Triple &Triple) : Generic_ELF(Host, Triple) { llvm::Triple::ArchType Arch = @@ -1370,42 +1458,23 @@ Linux::Linux(const HostInfo &Host, const llvm::Triple &Triple) } else if (Arch == llvm::Triple::ppc) { if (!llvm::sys::fs::exists("/usr/lib/powerpc-linux-gnu", Exists) && Exists) GccTriple = "powerpc-linux-gnu"; - else if (!llvm::sys::fs::exists("/usr/lib/gcc/powerpc-unknown-linux-gnu", Exists) && Exists) + else if (!llvm::sys::fs::exists("/usr/lib/gcc/powerpc-unknown-linux-gnu", + Exists) && Exists) GccTriple = "powerpc-unknown-linux-gnu"; } else if (Arch == llvm::Triple::ppc64) { - if (!llvm::sys::fs::exists("/usr/lib/gcc/powerpc64-unknown-linux-gnu", Exists) && Exists) + if (!llvm::sys::fs::exists("/usr/lib/gcc/powerpc64-unknown-linux-gnu", + Exists) && Exists) GccTriple = "powerpc64-unknown-linux-gnu"; - else if (!llvm::sys::fs::exists("/usr/lib64/gcc/powerpc64-unknown-linux-gnu", Exists) && Exists) + else if (!llvm::sys::fs::exists("/usr/lib64/gcc/" + "powerpc64-unknown-linux-gnu", Exists) && + Exists) GccTriple = "powerpc64-unknown-linux-gnu"; } - const char* GccVersions[] = {"4.6.0", - "4.5.2", "4.5.1", "4.5", - "4.4.5", "4.4.4", "4.4.3", "4.4", - "4.3.4", "4.3.3", "4.3.2", "4.3", - "4.2.4", "4.2.3", "4.2.2", "4.2.1", "4.2"}; - std::string Base = ""; - for (unsigned i = 0; i < sizeof(GccVersions)/sizeof(char*); ++i) { - std::string Suffix = GccTriple + "/" + GccVersions[i]; - std::string t1 = "/usr/lib/gcc/" + Suffix; - if (!llvm::sys::fs::exists(t1 + "/crtbegin.o", Exists) && Exists) { - Base = t1; - break; - } - std::string t2 = "/usr/lib64/gcc/" + Suffix; - if (!llvm::sys::fs::exists(t2 + "/crtbegin.o", Exists) && Exists) { - Base = t2; - break; - } - std::string t3 = "/usr/lib/" + GccTriple + "/gcc/" + Suffix; - if (!llvm::sys::fs::exists(t3 + "/crtbegin.o", Exists) && Exists) { - Base = t3; - break; - } - } - + std::string Base = findGCCBaseLibDir(GccTriple); path_list &Paths = getFilePaths(); - bool Is32Bits = (getArch() == llvm::Triple::x86 || getArch() == llvm::Triple::ppc); + bool Is32Bits = (getArch() == llvm::Triple::x86 || + getArch() == llvm::Triple::ppc); std::string Suffix; std::string Lib; @@ -1426,7 +1495,7 @@ Linux::Linux(const HostInfo &Host, const llvm::Triple &Triple) LinuxDistro Distro = DetectLinuxDistro(Arch); - if (IsUbuntu(Distro)) { + if (IsOpenSuse(Distro) || IsUbuntu(Distro)) { ExtraOpts.push_back("-z"); ExtraOpts.push_back("relro"); } @@ -1434,21 +1503,28 @@ Linux::Linux(const HostInfo &Host, const llvm::Triple &Triple) if (Arch == llvm::Triple::arm || Arch == llvm::Triple::thumb) ExtraOpts.push_back("-X"); - if (IsFedora(Distro) || Distro == UbuntuMaverick || Distro == UbuntuNatty) + if (IsRedhat(Distro) || IsOpenSuse(Distro) || Distro == UbuntuMaverick || + Distro == UbuntuNatty || Distro == UbuntuOneiric) ExtraOpts.push_back("--hash-style=gnu"); - if (IsDebian(Distro) || Distro == UbuntuLucid || Distro == UbuntuJaunty || - Distro == UbuntuKarmic) + if (IsDebian(Distro) || IsOpenSuse(Distro) || Distro == UbuntuLucid || + Distro == UbuntuJaunty || Distro == UbuntuKarmic) ExtraOpts.push_back("--hash-style=both"); - if (IsFedora(Distro)) + if (IsRedhat(Distro)) ExtraOpts.push_back("--no-add-needed"); - if (Distro == DebianSqueeze || IsOpenSuse(Distro) || - IsFedora(Distro) || Distro == UbuntuLucid || Distro == UbuntuMaverick || - Distro == UbuntuKarmic || Distro == UbuntuNatty) + if (Distro == DebianSqueeze || Distro == DebianWheezy || + IsOpenSuse(Distro) || + (IsRedhat(Distro) && Distro != RHEL4 && Distro != RHEL5) || + Distro == UbuntuLucid || + Distro == UbuntuMaverick || Distro == UbuntuKarmic || + Distro == UbuntuNatty || Distro == UbuntuOneiric) ExtraOpts.push_back("--build-id"); + if (IsOpenSuse(Distro)) + ExtraOpts.push_back("--enable-new-dtags"); + if (Distro == ArchLinux) Lib = "lib"; @@ -1457,9 +1533,14 @@ Linux::Linux(const HostInfo &Host, const llvm::Triple &Triple) if (IsOpenSuse(Distro) && Is32Bits) Paths.push_back(Base + "/../../../../" + GccTriple + "/lib/../lib"); Paths.push_back(Base + "/../../../../" + Lib); - Paths.push_back("/lib/../" + Lib); - Paths.push_back("/usr/lib/../" + Lib); } + + // FIXME: This is in here to find crt1.o. It is provided by libc, and + // libc (like gcc), can be installed in any directory. Once we are + // fetching this from a config file, we should have a libc prefix. + Paths.push_back("/lib/../" + Lib); + Paths.push_back("/usr/lib/../" + Lib); + if (!Suffix.empty()) Paths.push_back(Base); if (IsOpenSuse(Distro)) |