]> granicus.if.org Git - clang/commitdiff
[Driver] Do not lose already detected set of toolchain's multilibs while
authorSimon Atanasyan <simon@atanasyan.com>
Mon, 12 May 2014 07:37:51 +0000 (07:37 +0000)
committerSimon Atanasyan <simon@atanasyan.com>
Mon, 12 May 2014 07:37:51 +0000 (07:37 +0000)
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
lib/Driver/ToolChains.h
test/Driver/Inputs/ubuntu_14.04_multiarch_tree/lib/x86_64-linux-gnu/.keep [new file with mode: 0755]
test/Driver/Inputs/ubuntu_14.04_multiarch_tree/usr/include/c++/4.8/backward/.keep [new file with mode: 0755]
test/Driver/Inputs/ubuntu_14.04_multiarch_tree/usr/include/x86_64-linux-gnu/c++/4.8/32/.keep [new file with mode: 0755]
test/Driver/Inputs/ubuntu_14.04_multiarch_tree/usr/lib/gcc/x86_64-linux-gnu/4.8/32/crtbegin.o [new file with mode: 0755]
test/Driver/Inputs/ubuntu_14.04_multiarch_tree/usr/lib/gcc/x86_64-linux-gnu/4.8/crtbegin.o [new file with mode: 0755]
test/Driver/Inputs/ubuntu_14.04_multiarch_tree/usr/lib/gcc/x86_64-linux-gnu/4.9/.keep [new file with mode: 0644]
test/Driver/linux-header-search.cpp

index 0b77ee0c7be59f16374d8a42208fab727e2db8b0..b9e59e39fd662f023b57663142dd0cc195523c24 100644 (file)
@@ -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<Multilib> 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
index b1a06278403daf4d8519f87a4ae6c2ed8380cabb..7d69f7b8773c7a2dbe3ae66227ab690308addf4d 100644 (file)
@@ -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 (executable)
index 0000000..e69de29
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 (executable)
index 0000000..e69de29
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 (executable)
index 0000000..e69de29
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 (executable)
index 0000000..e69de29
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 (executable)
index 0000000..e69de29
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 (file)
index 0000000..e69de29
index 9d08d6f338adca83499cb18d7b3e7b1f38ac9b7b..b56a50a234d1e7f0f551c6946585f63192387cff 100644 (file)
 // 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 \