diff options
author | Michal Gorny <mgorny@gentoo.org> | 2016-12-12 15:07:43 +0000 |
---|---|---|
committer | Michal Gorny <mgorny@gentoo.org> | 2016-12-12 15:07:43 +0000 |
commit | f4debddb09d7a38f75f770b464abade47b522b1f (patch) | |
tree | b5d38907c401a0c05b1a3a12abbb9dda3f601769 /clang/lib | |
parent | b1227db1f4e5b2869463baa9beb43f007af4d24f (diff) | |
download | bcm5719-llvm-f4debddb09d7a38f75f770b464abade47b522b1f.tar.gz bcm5719-llvm-f4debddb09d7a38f75f770b464abade47b522b1f.zip |
[Driver] Fix finding multilib gcc install on Gentoo (with gcc-config)
Fix the gcc-config code to support multilib gcc installs properly. This
solves two problems: -mx32 using the 64-bit gcc directory (due to matching
installation triple), and -m32 not respecting gcc-config at all (due to
mismatched installation triple).
In order to fix the former issue, split the multilib scan out of
Generic_GCC::GCCInstallationDetector::ScanLibDirForGCCTriple() (the code
is otherwise unchanged), and call it for each installation found via
gcc-config.
In order to fix the latter issue, split the gcc-config processing out of
Generic_GCC::GCCInstallationDetector::init() and repeat it for all
triples, including extra and biarch triples. The only change
in the gcc-config code itself is adding the call to multilib scan.
Convert the gentoo_linux_gcc_multi_version_tree test input to multilib
x86_64+32+x32 install, and add appropriate tests to linux-header-search
and linux-ld.
Differential Revision: https://reviews.llvm.org/D26887
llvm-svn: 289436
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/Driver/ToolChains.cpp | 123 | ||||
-rw-r--r-- | clang/lib/Driver/ToolChains.h | 10 |
2 files changed, 88 insertions, 45 deletions
diff --git a/clang/lib/Driver/ToolChains.cpp b/clang/lib/Driver/ToolChains.cpp index be7fb7f59ef..1b1e04099cf 100644 --- a/clang/lib/Driver/ToolChains.cpp +++ b/clang/lib/Driver/ToolChains.cpp @@ -1457,35 +1457,17 @@ void Generic_GCC::GCCInstallationDetector::init( // in /usr. This avoids accidentally enforcing the system GCC version // when using a custom toolchain. if (GCCToolchainDir == "" || GCCToolchainDir == D.SysRoot + "/usr") { + for (StringRef CandidateTriple : ExtraTripleAliases) { + if (ScanGentooGccConfig(TargetTriple, Args, CandidateTriple)) + return; + } for (StringRef CandidateTriple : CandidateTripleAliases) { - llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> File = - D.getVFS().getBufferForFile(D.SysRoot + "/etc/env.d/gcc/config-" + - CandidateTriple.str()); - if (File) { - SmallVector<StringRef, 2> Lines; - File.get()->getBuffer().split(Lines, "\n"); - for (StringRef Line : Lines) { - // CURRENT=triple-version - if (Line.consume_front("CURRENT=")) { - const std::pair<StringRef, StringRef> ActiveVersion = - Line.rsplit('-'); - // Note: Strictly speaking, we should be reading - // /etc/env.d/gcc/${CURRENT} now. However, the file doesn't - // contain anything new or especially useful to us. - const std::string GentooPath = D.SysRoot + "/usr/lib/gcc/" + - ActiveVersion.first.str() + "/" + - ActiveVersion.second.str(); - if (D.getVFS().exists(GentooPath + "/crtbegin.o")) { - Version = GCCVersion::Parse(ActiveVersion.second); - GCCInstallPath = GentooPath; - GCCParentLibPath = GentooPath + "/../../.."; - GCCTriple.setTriple(ActiveVersion.first); - IsValid = true; - return; - } - } - } - } + if (ScanGentooGccConfig(TargetTriple, Args, CandidateTriple)) + return; + } + for (StringRef CandidateTriple : CandidateBiarchTripleAliases) { + if (ScanGentooGccConfig(TargetTriple, Args, CandidateTriple, true)) + return; } } @@ -2716,6 +2698,33 @@ void Generic_GCC::GCCInstallationDetector::scanLibDirForGCCTripleSolaris( } } +bool Generic_GCC::GCCInstallationDetector::ScanGCCForMultilibs( + const llvm::Triple &TargetTriple, const ArgList &Args, + StringRef Path, bool NeedsBiarchSuffix) { + llvm::Triple::ArchType TargetArch = TargetTriple.getArch(); + DetectedMultilibs Detected; + + // Android standalone toolchain could have multilibs for ARM and Thumb. + // Debian mips multilibs behave more like the rest of the biarch ones, + // so handle them there + if (isArmOrThumbArch(TargetArch) && TargetTriple.isAndroid()) { + // It should also work without multilibs in a simplified toolchain. + findAndroidArmMultilibs(D, TargetTriple, Path, Args, Detected); + } else if (isMipsArch(TargetArch)) { + if (!findMIPSMultilibs(D, TargetTriple, Path, Args, Detected)) + return false; + } else if (!findBiarchMultilibs(D, TargetTriple, Path, Args, + NeedsBiarchSuffix, Detected)) { + return false; + } + + Multilibs = Detected.Multilibs; + SelectedMultilib = Detected.SelectedMultilib; + BiarchSibling = Detected.BiarchSibling; + + return true; +} + void Generic_GCC::GCCInstallationDetector::ScanLibDirForGCCTriple( const llvm::Triple &TargetTriple, const ArgList &Args, const std::string &LibDir, StringRef CandidateTriple, @@ -2771,25 +2780,10 @@ void Generic_GCC::GCCInstallationDetector::ScanLibDirForGCCTriple( if (CandidateVersion <= Version) continue; - DetectedMultilibs Detected; - - // Android standalone toolchain could have multilibs for ARM and Thumb. - // Debian mips multilibs behave more like the rest of the biarch ones, - // so handle them there - if (isArmOrThumbArch(TargetArch) && TargetTriple.isAndroid()) { - // It should also work without multilibs in a simplified toolchain. - findAndroidArmMultilibs(D, TargetTriple, LI->getName(), Args, Detected); - } else if (isMipsArch(TargetArch)) { - if (!findMIPSMultilibs(D, TargetTriple, LI->getName(), Args, Detected)) - continue; - } else if (!findBiarchMultilibs(D, TargetTriple, LI->getName(), Args, - NeedsBiarchSuffix, Detected)) { + if (!ScanGCCForMultilibs(TargetTriple, Args, LI->getName(), + NeedsBiarchSuffix)) continue; - } - Multilibs = Detected.Multilibs; - SelectedMultilib = Detected.SelectedMultilib; - BiarchSibling = Detected.BiarchSibling; Version = CandidateVersion; GCCTriple.setTriple(CandidateTriple); // FIXME: We hack together the directory name here instead of @@ -2803,6 +2797,45 @@ void Generic_GCC::GCCInstallationDetector::ScanLibDirForGCCTriple( } } +bool Generic_GCC::GCCInstallationDetector::ScanGentooGccConfig( + const llvm::Triple &TargetTriple, const ArgList &Args, + StringRef CandidateTriple, bool NeedsBiarchSuffix) { + llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> File = + D.getVFS().getBufferForFile(D.SysRoot + "/etc/env.d/gcc/config-" + + CandidateTriple.str()); + if (File) { + SmallVector<StringRef, 2> Lines; + File.get()->getBuffer().split(Lines, "\n"); + for (StringRef Line : Lines) { + // CURRENT=triple-version + if (Line.consume_front("CURRENT=")) { + const std::pair<StringRef, StringRef> ActiveVersion = + Line.rsplit('-'); + // Note: Strictly speaking, we should be reading + // /etc/env.d/gcc/${CURRENT} now. However, the file doesn't + // contain anything new or especially useful to us. + const std::string GentooPath = D.SysRoot + "/usr/lib/gcc/" + + ActiveVersion.first.str() + "/" + + ActiveVersion.second.str(); + if (D.getVFS().exists(GentooPath + "/crtbegin.o")) { + if (!ScanGCCForMultilibs(TargetTriple, Args, GentooPath, + NeedsBiarchSuffix)) + return false; + + Version = GCCVersion::Parse(ActiveVersion.second); + GCCInstallPath = GentooPath; + GCCParentLibPath = GentooPath + "/../../.."; + GCCTriple.setTriple(ActiveVersion.first); + IsValid = true; + return true; + } + } + } + } + + return false; +} + Generic_GCC::Generic_GCC(const Driver &D, const llvm::Triple &Triple, const ArgList &Args) : ToolChain(D, Triple, Args), GCCInstallation(D), diff --git a/clang/lib/Driver/ToolChains.h b/clang/lib/Driver/ToolChains.h index 2abbd037281..0515aee808c 100644 --- a/clang/lib/Driver/ToolChains.h +++ b/clang/lib/Driver/ToolChains.h @@ -196,6 +196,11 @@ public: SmallVectorImpl<StringRef> &BiarchLibDirs, SmallVectorImpl<StringRef> &BiarchTripleAliases); + bool ScanGCCForMultilibs(const llvm::Triple &TargetTriple, + const llvm::opt::ArgList &Args, + StringRef Path, + bool NeedsBiarchSuffix = false); + void ScanLibDirForGCCTriple(const llvm::Triple &TargetArch, const llvm::opt::ArgList &Args, const std::string &LibDir, @@ -207,6 +212,11 @@ public: const std::string &LibDir, StringRef CandidateTriple, bool NeedsBiarchSuffix = false); + + bool ScanGentooGccConfig(const llvm::Triple &TargetTriple, + const llvm::opt::ArgList &Args, + StringRef CandidateTriple, + bool NeedsBiarchSuffix = false); }; protected: |