From 4be26d901c274e9ae283a9f7ed1b7a5ebc30121f Mon Sep 17 00:00:00 2001 From: Simon Atanasyan Date: Mon, 12 May 2014 07:37:51 +0000 Subject: [PATCH] [Driver] Do not lose already detected set of toolchain's multilibs while iterating over different library path suffixes and different library versions. To find the most appropriate library for the given command line flags we iterate over a set of disk paths. Before probe each path the already detected set of multilibs are cleared. If the set of paths contains existing paths which do not satisfy command line flags or do not contain necessary libraries and object files at all we might lose found multilibs. The patch updates variables which hold detected multilibs if we really find a new multilib matches command line flags. The patch reviewed by Jon Roelofs. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@208523 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Driver/ToolChains.cpp | 67 ++++++++++++------- lib/Driver/ToolChains.h | 7 -- .../lib/x86_64-linux-gnu/.keep | 0 .../usr/include/c++/4.8/backward/.keep | 0 .../include/x86_64-linux-gnu/c++/4.8/32/.keep | 0 .../gcc/x86_64-linux-gnu/4.8/32/crtbegin.o | 0 .../lib/gcc/x86_64-linux-gnu/4.8/crtbegin.o | 0 .../usr/lib/gcc/x86_64-linux-gnu/4.9/.keep | 0 test/Driver/linux-header-search.cpp | 14 ++++ 9 files changed, 55 insertions(+), 33 deletions(-) create mode 100755 test/Driver/Inputs/ubuntu_14.04_multiarch_tree/lib/x86_64-linux-gnu/.keep create mode 100755 test/Driver/Inputs/ubuntu_14.04_multiarch_tree/usr/include/c++/4.8/backward/.keep create mode 100755 test/Driver/Inputs/ubuntu_14.04_multiarch_tree/usr/include/x86_64-linux-gnu/c++/4.8/32/.keep create mode 100755 test/Driver/Inputs/ubuntu_14.04_multiarch_tree/usr/lib/gcc/x86_64-linux-gnu/4.8/32/crtbegin.o create mode 100755 test/Driver/Inputs/ubuntu_14.04_multiarch_tree/usr/lib/gcc/x86_64-linux-gnu/4.8/crtbegin.o create mode 100644 test/Driver/Inputs/ubuntu_14.04_multiarch_tree/usr/lib/gcc/x86_64-linux-gnu/4.9/.keep diff --git a/lib/Driver/ToolChains.cpp b/lib/Driver/ToolChains.cpp index 0b77ee0c7b..b9e59e39fd 100644 --- a/lib/Driver/ToolChains.cpp +++ b/lib/Driver/ToolChains.cpp @@ -1646,9 +1646,21 @@ static bool isMipsNan2008(const ArgList &Args) { return A && A->getValue() == StringRef("2008"); } -bool Generic_GCC::GCCInstallationDetector::findMIPSMultilibs( - const llvm::Triple &TargetTriple, StringRef Path, - const llvm::opt::ArgList &Args) { +struct DetectedMultilibs { + /// The set of multilibs that the detected installation supports. + MultilibSet Multilibs; + + /// The primary multilib appropriate for the given flags. + Multilib SelectedMultilib; + + /// On Biarch systems, this corresponds to the default multilib when + /// targeting the non-default multilib. Otherwise, it is empty. + llvm::Optional BiarchSibling; +}; + +static bool findMIPSMultilibs(const llvm::Triple &TargetTriple, StringRef Path, + const llvm::opt::ArgList &Args, + DetectedMultilibs &Result) { // Some MIPS toolchains put libraries and object files compiled // using different options in to the sub-directoris which names // reflects the flags used for compilation. For example sysroot @@ -1877,9 +1889,11 @@ bool Generic_GCC::GCCInstallationDetector::findMIPSMultilibs( if (TargetTriple.getEnvironment() == llvm::Triple::Android) { // Select Android toolchain. It's the only choice in that case. - Multilibs.clear(); - Multilibs.combineWith(AndroidMipsMultilibs); - return Multilibs.select(Flags, SelectedMultilib); + if (AndroidMipsMultilibs.select(Flags, Result.SelectedMultilib)) { + Result.Multilibs = AndroidMipsMultilibs; + return true; + } + return false; } // Sort candidates. Toolchain that best meets the directories goes first. @@ -1890,11 +1904,10 @@ bool Generic_GCC::GCCInstallationDetector::findMIPSMultilibs( std::begin(candidates), std::end(candidates), [](MultilibSet *a, MultilibSet *b) { return a->size() > b->size(); }); for (const auto &candidate : candidates) { - Multilibs.clear(); - Multilibs.combineWith(*candidate); - if (Multilibs.select(Flags, SelectedMultilib)) { + if (candidate->select(Flags, Result.SelectedMultilib)) { if (candidate == &DebianMipsMultilibs) - BiarchSibling = Multilib(); + Result.BiarchSibling = Multilib(); + Result.Multilibs = *candidate; return true; } } @@ -1902,9 +1915,10 @@ bool Generic_GCC::GCCInstallationDetector::findMIPSMultilibs( return false; } -bool Generic_GCC::GCCInstallationDetector::findBiarchMultilibs( - const llvm::Triple &TargetTriple, StringRef Path, const ArgList &Args, - bool NeedsBiarchSuffix) { +static bool findBiarchMultilibs(const llvm::Triple &TargetTriple, + StringRef Path, const ArgList &Args, + bool NeedsBiarchSuffix, + DetectedMultilibs &Result) { // Some versions of SUSE and Fedora on ppc64 put 32-bit libs // in what would normally be GCCInstallPath and put the 64-bit @@ -1944,22 +1958,21 @@ bool Generic_GCC::GCCInstallationDetector::findBiarchMultilibs( else Default.flag("-m32").flag("+m64"); - Multilibs.push_back(Default); - Multilibs.push_back(Alt64); - Multilibs.push_back(Alt32); + Result.Multilibs.push_back(Default); + Result.Multilibs.push_back(Alt64); + Result.Multilibs.push_back(Alt32); - Multilibs.FilterOut(NonExistent); + Result.Multilibs.FilterOut(NonExistent); Multilib::flags_list Flags; addMultilibFlag(TargetTriple.isArch64Bit(), "m64", Flags); addMultilibFlag(TargetTriple.isArch32Bit(), "m32", Flags); - if (!Multilibs.select(Flags, SelectedMultilib)) + if (!Result.Multilibs.select(Flags, Result.SelectedMultilib)) return false; - if (SelectedMultilib == Alt64 || SelectedMultilib == Alt32) { - BiarchSibling = Default; - } + if (Result.SelectedMultilib == Alt64 || Result.SelectedMultilib == Alt32) + Result.BiarchSibling = Default; return true; } @@ -2013,19 +2026,21 @@ void Generic_GCC::GCCInstallationDetector::ScanLibDirForGCCTriple( if (CandidateVersion <= Version) continue; - Multilibs.clear(); - SelectedMultilib = Multilib(); - BiarchSibling.reset(); + DetectedMultilibs Detected; // 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)) + if (!findMIPSMultilibs(TargetTriple, LI->path(), Args, Detected)) continue; } else if (!findBiarchMultilibs(TargetTriple, LI->path(), Args, - NeedsBiarchSuffix)) + NeedsBiarchSuffix, Detected)) { 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 diff --git a/lib/Driver/ToolChains.h b/lib/Driver/ToolChains.h index b1a0627840..7d69f7b877 100644 --- a/lib/Driver/ToolChains.h +++ b/lib/Driver/ToolChains.h @@ -145,13 +145,6 @@ protected: const std::string &LibDir, StringRef CandidateTriple, bool NeedsBiarchSuffix = false); - - bool findMIPSMultilibs(const llvm::Triple &TargetArch, StringRef Path, - const llvm::opt::ArgList &Args); - - bool findBiarchMultilibs(const llvm::Triple &TargetArch, StringRef Path, - const llvm::opt::ArgList &Args, - bool NeedsBiarchSuffix); }; GCCInstallationDetector GCCInstallation; diff --git a/test/Driver/Inputs/ubuntu_14.04_multiarch_tree/lib/x86_64-linux-gnu/.keep b/test/Driver/Inputs/ubuntu_14.04_multiarch_tree/lib/x86_64-linux-gnu/.keep new file mode 100755 index 0000000000..e69de29bb2 diff --git a/test/Driver/Inputs/ubuntu_14.04_multiarch_tree/usr/include/c++/4.8/backward/.keep b/test/Driver/Inputs/ubuntu_14.04_multiarch_tree/usr/include/c++/4.8/backward/.keep new file mode 100755 index 0000000000..e69de29bb2 diff --git a/test/Driver/Inputs/ubuntu_14.04_multiarch_tree/usr/include/x86_64-linux-gnu/c++/4.8/32/.keep b/test/Driver/Inputs/ubuntu_14.04_multiarch_tree/usr/include/x86_64-linux-gnu/c++/4.8/32/.keep new file mode 100755 index 0000000000..e69de29bb2 diff --git a/test/Driver/Inputs/ubuntu_14.04_multiarch_tree/usr/lib/gcc/x86_64-linux-gnu/4.8/32/crtbegin.o b/test/Driver/Inputs/ubuntu_14.04_multiarch_tree/usr/lib/gcc/x86_64-linux-gnu/4.8/32/crtbegin.o new file mode 100755 index 0000000000..e69de29bb2 diff --git a/test/Driver/Inputs/ubuntu_14.04_multiarch_tree/usr/lib/gcc/x86_64-linux-gnu/4.8/crtbegin.o b/test/Driver/Inputs/ubuntu_14.04_multiarch_tree/usr/lib/gcc/x86_64-linux-gnu/4.8/crtbegin.o new file mode 100755 index 0000000000..e69de29bb2 diff --git a/test/Driver/Inputs/ubuntu_14.04_multiarch_tree/usr/lib/gcc/x86_64-linux-gnu/4.9/.keep b/test/Driver/Inputs/ubuntu_14.04_multiarch_tree/usr/lib/gcc/x86_64-linux-gnu/4.9/.keep new file mode 100644 index 0000000000..e69de29bb2 diff --git a/test/Driver/linux-header-search.cpp b/test/Driver/linux-header-search.cpp index 9d08d6f338..b56a50a234 100644 --- a/test/Driver/linux-header-search.cpp +++ b/test/Driver/linux-header-search.cpp @@ -81,6 +81,20 @@ // CHECK-UBUNTU-13-04-M32: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/x86_64-linux-gnu/4.7/../../../../include/c++/4.7/backward" // CHECK-UBUNTU-13-04-M32: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/x86_64-linux-gnu/4.7/../../../../include/x86_64-linux-gnu/c++/4.7/32" // +// Test Ubuntu/Debian's Ubuntu 14.04 config variant, with -m32 +// and an empty 4.9 directory. +// RUN: %clang -no-canonical-prefixes %s -### -fsyntax-only 2>&1 \ +// RUN: -target x86_64-unknown-linux-gnu -m32 \ +// RUN: --sysroot=%S/Inputs/ubuntu_14.04_multiarch_tree \ +// RUN: | FileCheck --check-prefix=CHECK-UBUNTU-14-04-M32 %s +// CHECK-UBUNTU-14-04-M32: "{{[^"]*}}clang{{[^"]*}}" "-cc1" +// CHECK-UBUNTU-14-04-M32: "-triple" "i386-unknown-linux-gnu" +// CHECK-UBUNTU-14-04-M32: "-isysroot" "[[SYSROOT:[^"]+]]" +// CHECK-UBUNTU-14-04-M32: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8" +// CHECK-UBUNTU-14-04-M32: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/x86_64-linux-gnu/32" +// CHECK-UBUNTU-14-04-M32: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/backward" +// CHECK-UBUNTU-14-04-M32: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/x86_64-linux-gnu/c++/4.8/32" +// // Thoroughly exercise the Debian multiarch environment. // RUN: %clang -no-canonical-prefixes %s -### -fsyntax-only 2>&1 \ // RUN: -target i686-linux-gnu \ -- 2.40.0