diff options
Diffstat (limited to 'clang/lib/Driver/ToolChains.cpp')
-rw-r--r-- | clang/lib/Driver/ToolChains.cpp | 537 |
1 files changed, 375 insertions, 162 deletions
diff --git a/clang/lib/Driver/ToolChains.cpp b/clang/lib/Driver/ToolChains.cpp index f2155947586..60ca7ea195a 100644 --- a/clang/lib/Driver/ToolChains.cpp +++ b/clang/lib/Driver/ToolChains.cpp @@ -139,11 +139,11 @@ static const char *GetArmArchForMCpu(StringRef Value) { } static bool isSoftFloatABI(const ArgList &Args) { - Arg *A = Args.getLastArg(options::OPT_msoft_float, - options::OPT_mhard_float, + Arg *A = Args.getLastArg(options::OPT_msoft_float, options::OPT_mhard_float, options::OPT_mfloat_abi_EQ); - if (!A) return false; - + if (!A) + return false; + return A->getOption().matches(options::OPT_msoft_float) || (A->getOption().matches(options::OPT_mfloat_abi_EQ) && A->getValue() == StringRef("soft")); @@ -1175,7 +1175,7 @@ bool Generic_GCC::GCCVersion::isOlderThan(int RHSMajor, int RHSMinor, return false; } -static StringRef getGCCToolchainDir(const ArgList &Args) { +static llvm::StringRef getGCCToolchainDir(const ArgList &Args) { const Arg *A = Args.getLastArg(options::OPT_gcc_toolchain); if (A) return A->getValue(); @@ -1197,7 +1197,6 @@ Generic_GCC::GCCInstallationDetector::init( llvm::Triple BiarchVariantTriple = TargetTriple.isArch32Bit() ? TargetTriple.get64BitArchVariant() : TargetTriple.get32BitArchVariant(); - llvm::Triple::ArchType TargetArch = TargetTriple.getArch(); // The library directories which may contain GCC installations. SmallVector<StringRef, 4> CandidateLibDirs, CandidateBiarchLibDirs; // The compatible GCC triples for this particular architecture. @@ -1243,7 +1242,7 @@ Generic_GCC::GCCInstallationDetector::init( if (!llvm::sys::fs::exists(LibDir)) continue; for (unsigned k = 0, ke = CandidateTripleAliases.size(); k < ke; ++k) - ScanLibDirForGCCTriple(TargetArch, Args, LibDir, + ScanLibDirForGCCTriple(TargetTriple, Args, LibDir, CandidateTripleAliases[k]); } for (unsigned j = 0, je = CandidateBiarchLibDirs.size(); j < je; ++j) { @@ -1252,7 +1251,7 @@ Generic_GCC::GCCInstallationDetector::init( continue; for (unsigned k = 0, ke = CandidateBiarchTripleAliases.size(); k < ke; ++k) - ScanLibDirForGCCTriple(TargetArch, Args, LibDir, + ScanLibDirForGCCTriple(TargetTriple, Args, LibDir, CandidateBiarchTripleAliases[k], /*NeedsBiarchSuffix=*/ true); } @@ -1267,6 +1266,19 @@ void Generic_GCC::GCCInstallationDetector::print(raw_ostream &OS) const { OS << "Found candidate GCC installation: " << *I << "\n"; OS << "Selected GCC installation: " << GCCInstallPath << "\n"; + for (MultilibSet::const_iterator I = Multilibs.begin(), E = Multilibs.end(); + I != E; ++I) { + OS << "Candidate multiilb: " << *I << "\n"; + } + OS << "Selected multilib: " << SelectedMultilib << "\n"; +} + +bool Generic_GCC::GCCInstallationDetector::getBiarchSibling(Multilib &M) const { + if (BiarchSibling.hasValue()) { + M = BiarchSibling.getValue(); + return true; + } + return false; } /*static*/ void Generic_GCC::GCCInstallationDetector::CollectLibDirsAndTriples( @@ -1502,11 +1514,45 @@ void Generic_GCC::GCCInstallationDetector::print(raw_ostream &OS) const { BiarchTripleAliases.push_back(BiarchTriple.str()); } +namespace { +// Filter to remove Multilibs that don't exist as a suffix to Path +class FilterNonExistant : public MultilibSet::FilterCallback { + std::string Base; +public: + FilterNonExistant(std::string Base) : Base(Base) {} + bool operator()(const Multilib &M) const LLVM_OVERRIDE { + return !llvm::sys::fs::exists(Base + M.gccSuffix() + "/crtbegin.o"); + } +}; +} // end anonymous namespace + +static void addMultilibFlag(bool Enabled, const char *const Flag, + std::vector<std::string> &Flags) { + if (Enabled) + Flags.push_back(std::string("+") + Flag); + else + Flags.push_back(std::string("-") + Flag); +} + static bool isMipsArch(llvm::Triple::ArchType Arch) { - return Arch == llvm::Triple::mips || - Arch == llvm::Triple::mipsel || - Arch == llvm::Triple::mips64 || - Arch == llvm::Triple::mips64el; + return Arch == llvm::Triple::mips || Arch == llvm::Triple::mipsel || + Arch == llvm::Triple::mips64 || Arch == llvm::Triple::mips64el; +} + +static bool isMips32(llvm::Triple::ArchType Arch) { + return Arch == llvm::Triple::mips || Arch == llvm::Triple::mipsel; +} + +static bool isMips64(llvm::Triple::ArchType Arch) { + return Arch == llvm::Triple::mips64 || Arch == llvm::Triple::mips64el; +} + +static bool isMipsEL(llvm::Triple::ArchType Arch) { + return Arch == llvm::Triple::mipsel || Arch == llvm::Triple::mips64el; +} + +static bool isMipsEB(llvm::Triple::ArchType Arch) { + return Arch == llvm::Triple::mips || Arch == llvm::Triple::mips64; } static bool isMips16(const ArgList &Args) { @@ -1545,39 +1591,8 @@ static bool isMipsNan2008(const ArgList &Args) { return A && A->getValue() == StringRef("2008"); } -// FIXME: There is the same routine in the Tools.cpp. -static bool hasMipsABIArg(const ArgList &Args, const char *Value) { - Arg *A = Args.getLastArg(options::OPT_mabi_EQ); - return A && (A->getValue() == StringRef(Value)); -} - -static bool hasCrtBeginObj(Twine Path) { - return llvm::sys::fs::exists(Path + "/crtbegin.o"); -} - -static bool findTargetBiarchSuffix(std::string &Suffix, StringRef Path, - llvm::Triple::ArchType TargetArch, - const ArgList &Args) { - // FIXME: This routine was only intended to model bi-arch toolchains which - // use -m32 and -m64 to swap between variants of a target. It shouldn't be - // doing ABI-based builtin location for MIPS. - if (hasMipsABIArg(Args, "n32")) - Suffix = "/n32"; - else if (TargetArch == llvm::Triple::x86_64 || - TargetArch == llvm::Triple::ppc64 || - TargetArch == llvm::Triple::sparcv9 || - TargetArch == llvm::Triple::systemz || - TargetArch == llvm::Triple::mips64 || - TargetArch == llvm::Triple::mips64el) - Suffix = "/64"; - else - Suffix = "/32"; - - return hasCrtBeginObj(Path + Suffix); -} - -void Generic_GCC::GCCInstallationDetector::findMIPSABIDirSuffix( - std::string &Suffix, llvm::Triple::ArchType TargetArch, StringRef Path, +bool Generic_GCC::GCCInstallationDetector::findMIPSMultilibs( + const llvm::Triple &TargetTriple, StringRef Path, const llvm::opt::ArgList &Args) { // Some MIPS toolchains put libraries and object files compiled // using different options in to the sub-directoris which names @@ -1604,69 +1619,286 @@ void Generic_GCC::GCCInstallationDetector::findMIPSABIDirSuffix( // /usr // /lib <= crt*.o files compiled with '-mips32' - // Check FSF Toolchain path - Suffix.clear(); - if (TargetArch == llvm::Triple::mips || - TargetArch == llvm::Triple::mipsel) { - if (isMicroMips(Args)) - Suffix += "/micromips"; - else if (isMips32r2(Args)) - Suffix += ""; - else - Suffix += "/mips32"; + FilterNonExistant NonExistant(Path); + + // Check for FSF toolchain multilibs + MultilibSet FSFMipsMultilibs; + { + Multilib MArchMips32 = Multilib() + .gccSuffix("/mips32") + .osSuffix("/mips32") + .includeSuffix("/mips32") + .flag("+m32").flag("-m64").flag("-mmicromips").flag("-march=mips32r2"); + + Multilib MArchMicroMips = Multilib() + .gccSuffix("/micromips") + .osSuffix("/micromips") + .includeSuffix("/micromips") + .flag("+m32").flag("-m64").flag("+mmicromips"); + + Multilib MArchMips64r2 = Multilib() + .gccSuffix("/mips64r2") + .osSuffix("/mips64r2") + .includeSuffix("/mips64r2") + .flag("-m32").flag("+m64").flag("+march=mips64r2"); + + Multilib MArchMips64 = Multilib() + .gccSuffix("/mips64") + .osSuffix("/mips64") + .includeSuffix("/mips64") + .flag("-m32").flag("+m64").flag("-march=mips64r2"); + + Multilib MArchDefault = Multilib() + .flag("+m32").flag("-m64").flag("+march=mips32r2"); + + Multilib Mips16 = Multilib() + .gccSuffix("/mips16") + .osSuffix("/mips16") + .includeSuffix("/mips16") + .flag("+mips16"); + + Multilib MAbi64 = Multilib() + .gccSuffix("/64") + .osSuffix("/64") + .includeSuffix("/64") + .flag("+mabi=64").flag("-mabi=n32").flag("-m32"); + + Multilib LittleEndian = Multilib() + .gccSuffix("/el") + .osSuffix("/el") + .includeSuffix("/el") + .flag("+EL").flag("-EB"); + + Multilib SoftFloat = Multilib() + .gccSuffix("/sof") + .osSuffix("/sof") + .includeSuffix("/sof") + .flag("+msoft-float"); + + Multilib FP64 = Multilib() + .gccSuffix("/fp64") + .osSuffix("/fp64") + .includeSuffix("/fp64") + .flag("+mfp64"); + + Multilib Nan2008 = Multilib() + .gccSuffix("/nan2008") + .osSuffix("/nan2008") + .includeSuffix("/nan2008") + .flag("+mnan=2008"); + + FSFMipsMultilibs = MultilibSet() + .Either(MArchMips32, MArchMicroMips, + MArchMips64r2, MArchMips64, MArchDefault) + .Maybe(Mips16) + .FilterOut("/mips64/mips16") + .FilterOut("/mips64r2/mips16") + .FilterOut("/micromips/mips16") + .Maybe(MAbi64) + .FilterOut("/micromips/64") + .FilterOut("/mips32/64") + .FilterOut("^/64") + .FilterOut("/mips16/64") + .Maybe(LittleEndian) + .Maybe(SoftFloat) + .Maybe(FP64) + .Maybe(Nan2008) + .FilterOut(".*sof/nan2008") + .FilterOut(".*sof/fp64") + .FilterOut(NonExistant); + } + + // Check for Code Sourcery toolchain multilibs + MultilibSet CSMipsMultilibs; + { + Multilib MArchMips16 = Multilib() + .gccSuffix("/mips16") + .osSuffix("/mips16") + .includeSuffix("/mips16") + .flag("+m32").flag("+mips16"); + + Multilib MArchMicroMips = Multilib() + .gccSuffix("/micromips") + .osSuffix("/micromips") + .includeSuffix("/micromips") + .flag("+m32").flag("+mmicromips"); + + Multilib MArchDefault = Multilib() + .flag("-mips16").flag("-mmicromips"); + + Multilib SoftFloat = Multilib() + .gccSuffix("/soft-float") + .osSuffix("/soft-float") + .includeSuffix("/soft-float") + .flag("+msoft-float"); + + Multilib Nan2008 = Multilib() + .gccSuffix("/nan2008") + .osSuffix("/nan2008") + .includeSuffix("/nan2008") + .flag("+mnan=2008"); + + Multilib DefaultFloat = Multilib() + .flag("-msoft-float").flag("-mnan=2008"); + + Multilib LittleEndian = Multilib() + .gccSuffix("/el") + .osSuffix("/el") + .includeSuffix("/el") + .flag("+EL").flag("-EB"); + + // Note that this one's osSuffix is "" + Multilib MAbi64 = Multilib() + .gccSuffix("/64") + .includeSuffix("/64") + .flag("+mabi=64").flag("-mabi=n32").flag("-m32"); + + CSMipsMultilibs = MultilibSet() + .Either(MArchMips16, MArchMicroMips, MArchDefault) + .Either(SoftFloat, Nan2008, DefaultFloat) + .FilterOut("/micromips/nan2008") + .FilterOut("/mips16/nan2008") + .Maybe(LittleEndian) + .Maybe(MAbi64) + .FilterOut("/mips16.*/64") + .FilterOut("/micromips.*/64") + .FilterOut(NonExistant); + } + + MultilibSet AndroidMipsMultilibs = MultilibSet() + .Maybe(Multilib("/mips-r2").flag("+march=mips32r2")) + .FilterOut(NonExistant); + + MultilibSet DebianMipsMultilibs; + { + Multilib MAbiN32 = Multilib() + .gccSuffix("/n32") + .includeSuffix("/n32") + .flag("+mabi=n32"); + + Multilib M64 = Multilib() + .gccSuffix("/64") + .includeSuffix("/64") + .flag("+m64").flag("-m32").flag("-mabi=n32"); + + Multilib M32 = Multilib() + .flag("-m64").flag("+m32").flag("-mabi=n32"); + + DebianMipsMultilibs = MultilibSet() + .Either(M32, M64, MAbiN32) + .FilterOut(NonExistant); + } + + Multilibs.clear(); + + // Decide which MultilibSet matches best for the given path + // (we do this rather than combining them all because there is a + // a bit of overlap in the directories that each specifies) + if (TargetTriple.getEnvironment() == llvm::Triple::Android) + Multilibs.combineWith(AndroidMipsMultilibs); + else if (DebianMipsMultilibs.size() == 3) { + Multilibs.combineWith(DebianMipsMultilibs); + BiarchSibling = Multilib(); + } else if (FSFMipsMultilibs.size() > CSMipsMultilibs.size()) + Multilibs.combineWith(FSFMipsMultilibs); + else + Multilibs.combineWith(CSMipsMultilibs); - if (isMips16(Args)) - Suffix += "/mips16"; - } else { - if (isMips64r2(Args)) - Suffix += hasMipsABIArg(Args, "n32") ? "/mips64r2" : "/mips64r2/64"; - else - Suffix += hasMipsABIArg(Args, "n32") ? "/mips64" : "/mips64/64"; - } + llvm::Triple::ArchType TargetArch = TargetTriple.getArch(); - if (TargetArch == llvm::Triple::mipsel || - TargetArch == llvm::Triple::mips64el) - Suffix += "/el"; + Multilib::flags_list Flags; + addMultilibFlag(isMips32(TargetArch), "m32", Flags); + addMultilibFlag(isMips64(TargetArch), "m64", Flags); + addMultilibFlag(isMips16(Args), "mips16", Flags); + addMultilibFlag(isMips32r2(Args), "march=mips32r2", Flags); + addMultilibFlag(isMips64r2(Args), "march=mips64r2", Flags); + addMultilibFlag(isMicroMips(Args), "mmicromips", Flags); + addMultilibFlag(isMipsFP64(Args), "mfp64", Flags); + addMultilibFlag(!isMipsFP64(Args), "mfp32", Flags); + addMultilibFlag(isMipsNan2008(Args), "mnan=2008", Flags); + addMultilibFlag(tools::mips::hasMipsAbiArg(Args, "n32"), "mabi=n32", Flags); + // Default is to assume mabi=64 + bool IsMABI64 = + tools::mips::hasMipsAbiArg(Args, "64") || + (!tools::mips::hasMipsAbiArg(Args, "n32") && isMips64(TargetArch)); + addMultilibFlag(IsMABI64, "mabi=64", Flags); + addMultilibFlag(isSoftFloatABI(Args), "msoft-float", Flags); + addMultilibFlag(isSoftFloatABI(Args), "mfloat-abi=soft", Flags); + addMultilibFlag(!isSoftFloatABI(Args), "mhard-float", Flags); + addMultilibFlag(!isSoftFloatABI(Args), "mfloat-abi=hard", Flags); + addMultilibFlag(isMipsEL(TargetArch), "EL", Flags); + addMultilibFlag(isMipsEB(TargetArch), "EB", Flags); + + return Multilibs.select(Flags, SelectedMultilib); +} + +bool Generic_GCC::GCCInstallationDetector::findBiarchMultilibs( + const llvm::Triple &TargetTriple, StringRef Path, const ArgList &Args, + bool NeedsBiarchSuffix) { - if (isSoftFloatABI(Args)) - Suffix += "/sof"; + // Some versions of SUSE and Fedora on ppc64 put 32-bit libs + // in what would normally be GCCInstallPath and put the 64-bit + // libs in a subdirectory named 64. The simple logic we follow is that + // *if* there is a subdirectory of the right name with crtbegin.o in it, + // we use that. If not, and if not a biarch triple alias, we look for + // crtbegin.o without the subdirectory. + + Multilib Default; + Multilib Alt64 = Multilib() + .gccSuffix("/64") + .includeSuffix("/64") + .flag("-m32").flag("+m64"); + Multilib Alt32 = Multilib() + .gccSuffix("/32") + .includeSuffix("/32") + .flag("+m32").flag("-m64"); + + FilterNonExistant NonExistant(Path); + + // Decide whether the default multilib is 32bit, correcting for + // when the default multilib and the alternate appear backwards + bool DefaultIs32Bit; + if (TargetTriple.isArch32Bit() && !NonExistant(Alt32)) + DefaultIs32Bit = false; + else if (TargetTriple.isArch64Bit() && !NonExistant(Alt64)) + DefaultIs32Bit = true; else { - if (isMipsFP64(Args)) - Suffix += "/fp64"; - - if (isMipsNan2008(Args)) - Suffix += "/nan2008"; + if (NeedsBiarchSuffix) + DefaultIs32Bit = TargetTriple.isArch64Bit(); + else + DefaultIs32Bit = TargetTriple.isArch32Bit(); } - if (hasCrtBeginObj(Path + Suffix)) - return; + if (DefaultIs32Bit) + Default.flag("+m32").flag("-m64"); + else + Default.flag("-m32").flag("+m64"); - // Check Code Sourcery Toolchain path - Suffix.clear(); - if (isMips16(Args)) - Suffix += "/mips16"; - else if (isMicroMips(Args)) - Suffix += "/micromips"; + Multilibs.push_back(Default); + Multilibs.push_back(Alt64); + Multilibs.push_back(Alt32); - if (isSoftFloatABI(Args)) - Suffix += "/soft-float"; - else if (isMipsNan2008(Args)) - Suffix += "/nan2008"; + Multilibs.FilterOut(NonExistant); - if (TargetArch == llvm::Triple::mipsel || - TargetArch == llvm::Triple::mips64el) - Suffix += "/el"; + Multilib::flags_list Flags; + addMultilibFlag(TargetTriple.isArch64Bit(), "m64", Flags); + addMultilibFlag(TargetTriple.isArch32Bit(), "m32", Flags); - if (hasCrtBeginObj(Path + Suffix)) - return; + if (!Multilibs.select(Flags, SelectedMultilib)) + return false; - Suffix.clear(); + if (SelectedMultilib == Alt64 || SelectedMultilib == Alt32) { + BiarchSibling = Default; + } + + return true; } void Generic_GCC::GCCInstallationDetector::ScanLibDirForGCCTriple( - llvm::Triple::ArchType TargetArch, const ArgList &Args, + const llvm::Triple &TargetTriple, const ArgList &Args, const std::string &LibDir, StringRef CandidateTriple, bool NeedsBiarchSuffix) { + llvm::Triple::ArchType TargetArch = TargetTriple.getArch(); // There are various different suffixes involving the triple we // check for. We also record what is necessary to walk from each back // up to the lib directory. @@ -1711,28 +1943,18 @@ void Generic_GCC::GCCInstallationDetector::ScanLibDirForGCCTriple( if (CandidateVersion <= Version) continue; - std::string MIPSABIDirSuffix; - if (isMipsArch(TargetArch)) - findMIPSABIDirSuffix(MIPSABIDirSuffix, TargetArch, LI->path(), Args); - - // Some versions of SUSE and Fedora on ppc64 put 32-bit libs - // in what would normally be GCCInstallPath and put the 64-bit - // libs in a subdirectory named 64. The simple logic we follow is that - // *if* there is a subdirectory of the right name with crtbegin.o in it, - // we use that. If not, and if not a biarch triple alias, we look for - // crtbegin.o without the subdirectory. - - std::string BiarchSuffix; - if (findTargetBiarchSuffix(BiarchSuffix, - LI->path() + MIPSABIDirSuffix, - TargetArch, Args)) { - GCCBiarchSuffix = BiarchSuffix; - } else if (NeedsBiarchSuffix || - !hasCrtBeginObj(LI->path() + MIPSABIDirSuffix)) { + Multilibs.clear(); + SelectedMultilib = Multilib(); + BiarchSibling.reset(); + + // Debian mips multilibs behave more like the rest of the biarch ones, + // so handle them there + if (isMipsArch(TargetArch)) { + if (!findMIPSMultilibs(TargetTriple, LI->path(), Args)) + continue; + } else if (!findBiarchMultilibs(TargetTriple, LI->path(), Args, + NeedsBiarchSuffix)) continue; - } else { - GCCBiarchSuffix.clear(); - } Version = CandidateVersion; GCCTriple.setTriple(CandidateTriple); @@ -1741,7 +1963,6 @@ void Generic_GCC::GCCInstallationDetector::ScanLibDirForGCCTriple( // Linux. GCCInstallPath = LibDir + LibSuffixes[i] + "/" + VersionText.str(); GCCParentLibPath = GCCInstallPath + InstallSuffixes[i]; - GCCMIPSABIDirSuffix = MIPSABIDirSuffix; IsValid = true; } } @@ -2250,9 +2471,9 @@ NetBSD::NetBSD(const Driver &D, const llvm::Triple& Triple, const ArgList &Args) break; case llvm::Triple::mips64: case llvm::Triple::mips64el: - if (hasMipsABIArg(Args, "o32")) + if (tools::mips::hasMipsAbiArg(Args, "o32")) getFilePaths().push_back("=/usr/lib/o32"); - else if (hasMipsABIArg(Args, "64")) + else if (tools::mips::hasMipsAbiArg(Args, "64")) getFilePaths().push_back("=/usr/lib/64"); break; default: @@ -2566,25 +2787,24 @@ static void addPathIfExists(Twine Path, ToolChain::path_list &Paths) { if (llvm::sys::fs::exists(Path)) Paths.push_back(Path.str()); } -static StringRef getMultilibDir(const llvm::Triple &Triple, - const ArgList &Args) { +static StringRef getOSLibDir(const llvm::Triple &Triple, const ArgList &Args) { if (isMipsArch(Triple.getArch())) { // 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 (hasMipsABIArg(Args, "n32")) + 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 multilib, and + // 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' multilib search path being considered. So we only enable + // 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 multilib spellings with the lib dir spellings in the + // 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) @@ -2596,6 +2816,7 @@ static StringRef getMultilibDir(const llvm::Triple &Triple, Linux::Linux(const Driver &D, const llvm::Triple &Triple, const ArgList &Args) : Generic_ELF(D, Triple, Args) { GCCInstallation.init(D, Triple, Args); + Multilibs = GCCInstallation.getMultilibs(); llvm::Triple::ArchType Arch = Triple.getArch(); std::string SysRoot = computeSysRoot(); @@ -2663,29 +2884,20 @@ Linux::Linux(const Driver &D, const llvm::Triple &Triple, const ArgList &Args) // to the link paths. path_list &Paths = getFilePaths(); - const std::string Multilib = getMultilibDir(Triple, Args); + const std::string OSLibDir = getOSLibDir(Triple, Args); const std::string MultiarchTriple = getMultiarchTriple(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(); // Sourcery CodeBench MIPS toolchain holds some libraries under // a biarch-like suffix of the GCC installation. - // - // FIXME: It would be cleaner to model this as a variant of bi-arch. IE, - // instead of a '64' biarch suffix it would be 'el' or something. - if (IsAndroid && IsMips && isMips32r2(Args)) { - assert(GCCInstallation.getBiarchSuffix().empty() && - "Unexpected bi-arch suffix"); - addPathIfExists(GCCInstallation.getInstallPath() + "/mips-r2", Paths); - } else { - addPathIfExists((GCCInstallation.getInstallPath() + - GCCInstallation.getMIPSABIDirSuffix() + - GCCInstallation.getBiarchSuffix()), - Paths); - } + addPathIfExists((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 @@ -2705,8 +2917,8 @@ Linux::Linux(const Driver &D, const llvm::Triple &Triple, const ArgList &Args) // // Note that this matches the GCC behavior. See the below comment for where // Clang diverges from GCC's behavior. - addPathIfExists(LibPath + "/../" + GCCTriple.str() + "/lib/../" + Multilib + - GCCInstallation.getMIPSABIDirSuffix(), + addPathIfExists(LibPath + "/../" + GCCTriple.str() + "/lib/../" + OSLibDir + + Multilib.osSuffix(), Paths); // If the GCC installation we found is inside of the sysroot, we want to @@ -2720,42 +2932,45 @@ Linux::Linux(const Driver &D, const llvm::Triple &Triple, const ArgList &Args) // a bug. if (StringRef(LibPath).startswith(SysRoot)) { addPathIfExists(LibPath + "/" + MultiarchTriple, Paths); - addPathIfExists(LibPath + "/../" + Multilib, Paths); + addPathIfExists(LibPath + "/../" + OSLibDir, Paths); } } // Similar to the logic for GCC above, if we currently running Clang inside - // of the requested system root, add its parent multilib library paths to + // 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.Dir + "/../lib/" + MultiarchTriple, Paths); - addPathIfExists(D.Dir + "/../" + Multilib, Paths); + addPathIfExists(D.Dir + "/../" + OSLibDir, Paths); } addPathIfExists(SysRoot + "/lib/" + MultiarchTriple, Paths); - addPathIfExists(SysRoot + "/lib/../" + Multilib, Paths); + addPathIfExists(SysRoot + "/lib/../" + OSLibDir, Paths); addPathIfExists(SysRoot + "/usr/lib/" + MultiarchTriple, Paths); - addPathIfExists(SysRoot + "/usr/lib/../" + Multilib, Paths); + addPathIfExists(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(SysRoot + "/usr/lib/" + GCCInstallation.getTriple().str() + - "/../../" + Multilib, Paths); + "/../../" + OSLibDir, Paths); - // Add the non-multilib suffixed paths (if potentially different). - const std::string &LibPath = GCCInstallation.getParentLibPath(); - const llvm::Triple &GCCTriple = GCCInstallation.getTriple(); - if (!GCCInstallation.getBiarchSuffix().empty()) + // Add the 'other' biarch variant path + Multilib BiarchSibling; + if (GCCInstallation.getBiarchSibling(BiarchSibling)) { addPathIfExists(GCCInstallation.getInstallPath() + - GCCInstallation.getMIPSABIDirSuffix(), Paths); + 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(LibPath + "/../" + GCCTriple.str() + - "/lib" + GCCInstallation.getMIPSABIDirSuffix(), Paths); + "/lib" + Multilib.osSuffix(), Paths); // See comments above on the multilib variant for details of why this is // only included from within the sysroot. @@ -2804,15 +3019,15 @@ std::string Linux::computeSysRoot() const { const StringRef InstallDir = GCCInstallation.getInstallPath(); const StringRef TripleStr = GCCInstallation.getTriple().str(); - const StringRef MIPSABIDirSuffix = GCCInstallation.getMIPSABIDirSuffix(); + const Multilib &Multilib = GCCInstallation.getMultilib(); std::string Path = (InstallDir + "/../../../../" + TripleStr + "/libc" + - MIPSABIDirSuffix).str(); + Multilib.osSuffix()).str(); if (llvm::sys::fs::exists(Path)) return Path; - Path = (InstallDir + "/../../../../sysroot" + MIPSABIDirSuffix).str(); + Path = (InstallDir + "/../../../../sysroot" + Multilib.osSuffix()).str(); if (llvm::sys::fs::exists(Path)) return Path; @@ -2968,17 +3183,16 @@ void Linux::AddClangSystemIncludeArgs(const ArgList &DriverArgs, /// libstdc++ installation. /*static*/ bool Linux::addLibStdCXXIncludePaths(Twine Base, Twine Suffix, Twine TargetArchDir, - Twine BiarchSuffix, - Twine MIPSABIDirSuffix, + Twine IncludeSuffix, const ArgList &DriverArgs, ArgStringList &CC1Args) { if (!addLibStdCXXIncludePaths(Base + Suffix, - TargetArchDir + MIPSABIDirSuffix + BiarchSuffix, + TargetArchDir + IncludeSuffix, DriverArgs, CC1Args)) return false; addSystemInclude(DriverArgs, CC1Args, Base + "/" + TargetArchDir + Suffix - + MIPSABIDirSuffix + BiarchSuffix); + + IncludeSuffix); return true; } @@ -3022,13 +3236,12 @@ void Linux::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs, StringRef LibDir = GCCInstallation.getParentLibPath(); StringRef InstallDir = GCCInstallation.getInstallPath(); StringRef TripleStr = GCCInstallation.getTriple().str(); - StringRef MIPSABIDirSuffix = GCCInstallation.getMIPSABIDirSuffix(); - StringRef BiarchSuffix = GCCInstallation.getBiarchSuffix(); + const Multilib &Multilib = GCCInstallation.getMultilib(); const GCCVersion &Version = GCCInstallation.getVersion(); if (addLibStdCXXIncludePaths(LibDir.str() + "/../include", - "/c++/" + Version.Text, TripleStr, BiarchSuffix, - MIPSABIDirSuffix, DriverArgs, CC1Args)) + "/c++/" + Version.Text, TripleStr, + Multilib.includeSuffix(), DriverArgs, CC1Args)) return; const std::string LibStdCXXIncludePathCandidates[] = { @@ -3047,7 +3260,7 @@ void Linux::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs, for (unsigned i = 0; i < llvm::array_lengthof(LibStdCXXIncludePathCandidates); ++i) { if (addLibStdCXXIncludePaths(LibStdCXXIncludePathCandidates[i], - TripleStr + MIPSABIDirSuffix + BiarchSuffix, + TripleStr + Multilib.includeSuffix(), DriverArgs, CC1Args)) break; } |