diff options
author | Chandler Carruth <chandlerc@gmail.com> | 2011-10-16 10:54:30 +0000 |
---|---|---|
committer | Chandler Carruth <chandlerc@gmail.com> | 2011-10-16 10:54:30 +0000 |
commit | 7a09d012f6d52c8a7ba257df85d13149e6aa7cb2 (patch) | |
tree | 4a53fb29be81ab26a8b704b3262063c81a5e3a93 /lib/Driver/ToolChains.cpp | |
parent | 96fda0c4a7bb5502d82791f361997471c173b909 (diff) |
Clean up some cruft in the library path searching logic by making
'libdir' mean the actual library directory, not the GCC subdirectory of
the library directory. That was just a confusing pattern. Instead,
supply proper GCC subdirectories when scanning for various triple-based
subdirectories with a GCC installation in them. This also makes it much
more obvious how multiarch installations, which have a triple-based
prefix as well as suffix work.
Also clean up our handling of these triple-prefixed trees by using them
in both a multiarch pattern and a non-multiarch pattern whenever they
exist.
Note that this *does not* match what GCC does on Debian, the only truly
multiarch installation I've been able to get installed and test on. GCC
appears to have a bug, and ends up searching paths like
'/lib/../../lib32' which makes no sense what-so-ever. Instead, I've
tried to encode the rational logic that seems clearly intended by GCC's
pattern. GCC ends up with patterns like:
/lib/../../lib32
/usr/lib/../../lib32
/usr/lib/x86_64-linux-gnu/../..lib32
Only the last one makes any sense having a '/../..' in it, so in Clang,
that's the only one which gets a '/../..' in it.
I *think* this will fix Debian multiarch links. I'm committing without
baking this logic into our test suite so I can test on a few different
systems. If all goes well (and no one screams) I'll check in some more
comprehensive tests for multiarch behavior tomorrow.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@142133 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Driver/ToolChains.cpp')
-rw-r--r-- | lib/Driver/ToolChains.cpp | 61 |
1 files changed, 34 insertions, 27 deletions
diff --git a/lib/Driver/ToolChains.cpp b/lib/Driver/ToolChains.cpp index 273f4b4bf1..2ce0d8082e 100644 --- a/lib/Driver/ToolChains.cpp +++ b/lib/Driver/ToolChains.cpp @@ -1631,14 +1631,12 @@ private: SmallVectorImpl<StringRef> &LibDirs, SmallVectorImpl<StringRef> &Triples) { if (HostArch == llvm::Triple::arm || HostArch == llvm::Triple::thumb) { - static const char *const ARMLibDirs[] = { "/lib/gcc" }; + static const char *const ARMLibDirs[] = { "/lib" }; static const char *const ARMTriples[] = { "arm-linux-gnueabi" }; LibDirs.append(ARMLibDirs, ARMLibDirs + llvm::array_lengthof(ARMLibDirs)); Triples.append(ARMTriples, ARMTriples + llvm::array_lengthof(ARMTriples)); } else if (HostArch == llvm::Triple::x86_64) { - static const char *const X86_64LibDirs[] = { - "/lib64/gcc", "/lib/gcc", "/lib64", "/lib" - }; + static const char *const X86_64LibDirs[] = { "/lib64", "/lib" }; static const char *const X86_64Triples[] = { "x86_64-linux-gnu", "x86_64-unknown-linux-gnu", @@ -1655,9 +1653,7 @@ private: Triples.append(X86_64Triples, X86_64Triples + llvm::array_lengthof(X86_64Triples)); } else if (HostArch == llvm::Triple::x86) { - static const char *const X86LibDirs[] = { - "/lib32/gcc", "/lib/gcc", "/lib32", "/lib" - }; + static const char *const X86LibDirs[] = { "/lib32", "/lib" }; static const char *const X86Triples[] = { "i686-linux-gnu", "i386-linux-gnu", @@ -1671,9 +1667,7 @@ private: LibDirs.append(X86LibDirs, X86LibDirs + llvm::array_lengthof(X86LibDirs)); Triples.append(X86Triples, X86Triples + llvm::array_lengthof(X86Triples)); } else if (HostArch == llvm::Triple::ppc) { - static const char *const PPCLibDirs[] = { - "/lib32/gcc", "/lib/gcc", "/lib32", "/lib" - }; + static const char *const PPCLibDirs[] = { "/lib32", "/lib" }; static const char *const PPCTriples[] = { "powerpc-linux-gnu", "powerpc-unknown-linux-gnu" @@ -1681,9 +1675,7 @@ private: LibDirs.append(PPCLibDirs, PPCLibDirs + llvm::array_lengthof(PPCLibDirs)); Triples.append(PPCTriples, PPCTriples + llvm::array_lengthof(PPCTriples)); } else if (HostArch == llvm::Triple::ppc64) { - static const char *const PPC64LibDirs[] = { - "/lib64/gcc", "/lib/gcc", "/lib64", "/lib" - }; + static const char *const PPC64LibDirs[] = { "/lib64", "/lib" }; static const char *const PPC64Triples[] = { "powerpc64-unknown-linux-gnu" }; @@ -1697,23 +1689,31 @@ private: void ScanLibDirForGCCTriple(const std::string &LibDir, StringRef CandidateTriple, GCCVersion &BestVersion) { - const std::string TripleDir = LibDir + "/" + CandidateTriple.str(); - if (!PathExists(TripleDir)) - return; - - // There are various different suffixes on the triple directory we + // 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. - const std::string Suffixes[] = { "", "/gcc/" + CandidateTriple.str(), - "/gcc/i686-linux-gnu" }; - const std::string InstallSuffixes[] = { "/../../..", "/../../../..", - "/../../../.." }; + const std::string Suffixes[] = { + "/gcc/" + CandidateTriple.str(), + CandidateTriple.str() + "/gcc/" + CandidateTriple.str(), + + // Ubuntu has a strange mis-matched pair of triples that this happens to + // match. + // FIXME: It may be worthwhile to generalize this and look for a second + // triple. + CandidateTriple.str() + "/gcc/i686-linux-gnu" + }; + const std::string InstallSuffixes[] = { + "/../../..", + "/../../../..", + "/../../../.." + }; + // Only look at the final, weird Ubuntu suffix for i386-linux-gnu. const unsigned NumSuffixes = (llvm::array_lengthof(Suffixes) - (CandidateTriple != "i386-linux-gnu")); for (unsigned i = 0; i < NumSuffixes; ++i) { StringRef Suffix = Suffixes[i]; llvm::error_code EC; - for (llvm::sys::fs::directory_iterator LI(TripleDir + Suffix, EC), LE; + for (llvm::sys::fs::directory_iterator LI(LibDir + Suffix, EC), LE; !EC && LI != LE; LI = LI.increment(EC)) { StringRef VersionText = llvm::sys::path::filename(LI->path()); GCCVersion CandidateVersion = GCCVersion::Parse(VersionText); @@ -1730,7 +1730,7 @@ private: // FIXME: We hack together the directory name here instead of // using LI to ensure stable path separators across Windows and // Linux. - GccInstallPath = TripleDir + Suffixes[i] + "/" + VersionText.str(); + GccInstallPath = LibDir + Suffixes[i] + "/" + VersionText.str(); GccParentLibPath = GccInstallPath + InstallSuffixes[i]; IsValid = true; } @@ -1825,9 +1825,15 @@ Linux::Linux(const HostInfo &Host, const llvm::Triple &Triple) } addPathIfExists(SysRoot + "/lib/../" + Multilib, Paths); addPathIfExists(SysRoot + "/usr/lib/../" + Multilib, Paths); + + // Try walking via the GCC triple path in case of multiarch GCC + // installations with strange symlinks. + if (GCCInstallation.isValid()) + addPathIfExists(SysRoot + "/usr/lib/" + GCCInstallation.getTriple() + + "/../../" + Multilib, Paths); } - // Add the non-multiplib suffixed paths (if potentially different). + // Add the non-multilib suffixed paths (if potentially different). if (GCCInstallation.isValid()) { const std::string &LibPath = GCCInstallation.getParentLibPath(); const std::string &GccTriple = GCCInstallation.getTriple(); @@ -1839,8 +1845,9 @@ Linux::Linux(const HostInfo &Host, const llvm::Triple &Triple) addPathIfExists(SysRoot + "/lib", Paths); addPathIfExists(SysRoot + "/usr/lib", Paths); - if (GCCInstallation.isValid() && Arch == getArch() && IsUbuntu(Distro)) - Paths.push_back(SysRoot + "/usr/lib/" + GCCInstallation.getTriple()); + // Add a multiarch lib directory whenever it exists and is plausible. + if (GCCInstallation.isValid() && Arch == getArch()) + addPathIfExists(SysRoot + "/usr/lib/" + GCCInstallation.getTriple(), Paths); } bool Linux::HasNativeLLVMSupport() const { |