manojgupta updated this revision to Diff 141019.
manojgupta added a comment.

Address requested changes.


Repository:
  rC Clang

https://reviews.llvm.org/D45233

Files:
  lib/Driver/ToolChains/Gnu.cpp
  lib/Driver/ToolChains/Gnu.h

Index: lib/Driver/ToolChains/Gnu.h
===================================================================
--- lib/Driver/ToolChains/Gnu.h
+++ lib/Driver/ToolChains/Gnu.h
@@ -265,9 +265,15 @@
                                 StringRef CandidateTriple,
                                 bool NeedsBiarchSuffix = false);
 
+    bool ScanGentooConfigs(const llvm::Triple &TargetTriple,
+                           const llvm::opt::ArgList &Args,
+                           const SmallVectorImpl<StringRef> &CandidateTriples,
+                           const SmallVectorImpl<StringRef> &BiarchTriples);
+
     bool ScanGentooGccConfig(const llvm::Triple &TargetTriple,
                              const llvm::opt::ArgList &Args,
                              StringRef CandidateTriple,
+                             const std::string& SysRootPrefix,
                              bool NeedsBiarchSuffix = false);
   };
 
Index: lib/Driver/ToolChains/Gnu.cpp
===================================================================
--- lib/Driver/ToolChains/Gnu.cpp
+++ lib/Driver/ToolChains/Gnu.cpp
@@ -1707,18 +1707,21 @@
   // 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) {
-      if (ScanGentooGccConfig(TargetTriple, Args, CandidateTriple))
-        return;
-    }
-    for (StringRef CandidateTriple : CandidateBiarchTripleAliases) {
-      if (ScanGentooGccConfig(TargetTriple, Args, CandidateTriple, true))
-        return;
-    }
+    SmallVector<StringRef, 16> GentooTestTriples;
+    // Try to match an exact triple as target triple first.
+    // e.g. crossdev -S x86_64-gentoo-linux-gnu will install gcc libs for
+    // x86_64-gentoo-linux-gnu. But "clang -target x86_64-gentoo-linux-gnu"
+    // may pick the libraries for x86_64-pc-linux-gnu even when exact matching
+    // triple x86_64-gentoo-linux-gnu is present.
+    GentooTestTriples.push_back(TargetTriple.str());
+    // Check rest of triples.
+    GentooTestTriples.append(ExtraTripleAliases.begin(),
+                             ExtraTripleAliases.end());
+    GentooTestTriples.append(CandidateTripleAliases.begin(),
+                             CandidateTripleAliases.end());
+    if (ScanGentooConfigs(TargetTriple, Args, GentooTestTriples,
+                          CandidateBiarchTripleAliases))
+      return;
   }
 
   // Loop over the various components which exist and select the best GCC
@@ -2224,38 +2227,100 @@
   }
 }
 
+bool Generic_GCC::GCCInstallationDetector::ScanGentooConfigs(
+    const llvm::Triple &TargetTriple, const ArgList &Args,
+    const SmallVectorImpl<StringRef> &CandidateTriples,
+    const SmallVectorImpl<StringRef> &CandidateBiarchTriples) {
+  // First scan libraries from the sysroot directory if specified.
+  // If not sucessful, scan the root directories. This is needed to find
+  // cross-compilation files/libraries installed by crossdev. For instance,
+  // crossdev -S aarch64-gentoo-linux-gnu installs GCC libraries in
+  // /usr/lib/gcc/version/aarch64-gentoo-linux-gnu and the headers are
+  // installed at /usr/aarch64-gentoo-linux-gnu. Sysroot argument is
+  // needed to find the headers installed in /usr/aarch64-gentoo-linux-gnu.
+  SmallVector<std::string, 2> SysRootPrefixes;
+  if (!D.SysRoot.empty()) {
+    SysRootPrefixes.push_back(D.SysRoot);
+  }
+  SysRootPrefixes.push_back("");
+
+  for (const std::string &SysRoot : SysRootPrefixes) {
+    for (StringRef CandidateTriple : CandidateTriples) {
+      if (ScanGentooGccConfig(TargetTriple, Args, CandidateTriple, SysRoot))
+        return true;
+    }
+
+    for (StringRef CandidateTriple : CandidateBiarchTriples) {
+      if (ScanGentooGccConfig(TargetTriple, Args, CandidateTriple, SysRoot,
+                              true))
+        return true;
+    }
+  }
+  return false;
+}
+
 bool Generic_GCC::GCCInstallationDetector::ScanGentooGccConfig(
     const llvm::Triple &TargetTriple, const ArgList &Args,
-    StringRef CandidateTriple, bool NeedsBiarchSuffix) {
+    StringRef CandidateTriple, const std::string &SysRootPrefix,
+    bool NeedsBiarchSuffix) {
   llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> File =
-      D.getVFS().getBufferForFile(D.SysRoot + "/etc/env.d/gcc/config-" +
+      D.getVFS().getBufferForFile(SysRootPrefix + "/etc/env.d/gcc/config-" +
                                   CandidateTriple.str());
   if (File) {
     SmallVector<StringRef, 2> Lines;
     File.get()->getBuffer().split(Lines, "\n");
     for (StringRef Line : Lines) {
       Line = Line.trim();
       // 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;
+        // Actual config file pointed to by CURRENT.
+        llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> ConfigFile =
+            D.getVFS().getBufferForFile(SysRootPrefix + "/etc/env.d/gcc/" +
+                                        Line.str());
+        std::pair<StringRef, StringRef> ActiveVersion = Line.rsplit('-');
+        // List of paths to scan for libraries.
+        SmallVector<StringRef, 4> GentooScanPaths;
+        // Scan the Config file to find installed GCC libraries path.
+        // A typical content of gcc config file:
+        // LDPATH="/usr/lib/gcc/x86_64-pc-linux-gnu/4.9.x:/usr/lib/gcc/
+        // (continued from previous line) x86_64-pc-linux-gnu/4.9.x/32"
+        // MANPATH="/usr/share/gcc-data/x86_64-pc-linux-gnu/4.9.x/man"
+        // INFOPATH="/usr/share/gcc-data/x86_64-pc-linux-gnu/4.9.x/info"
+        // STDCXX_INCDIR="/usr/lib/gcc/x86_64-pc-linux-gnu/4.9.x/include/g++-v4"
+        // We are looking for the paths listed in LDPATH=... .
+        if (ConfigFile) {
+          SmallVector<StringRef, 2> ConfigLines;
+          ConfigFile.get()->getBuffer().split(ConfigLines, "\n");
+          for (StringRef ConfLine : ConfigLines) {
+            ConfLine = ConfLine.trim();
+            if (ConfLine.consume_front("LDPATH=")) {
+              // Drop '"' from front and back if present.
+              ConfLine.consume_back("\"");
+              ConfLine.consume_front("\"");
+              // Get all paths sperated by ':'
+              ConfLine.split(GentooScanPaths, ':', -1, /*AllowEmpty*/ false);
+            }
+          }
+        }
+        // Test the path based on the version in /etc/env.d/gcc/config-{tuple}.
+        std::string basePath = SysRootPrefix + "/usr/lib/gcc/" +
+            ActiveVersion.first.str() + "/" + ActiveVersion.second.str();
+        GentooScanPaths.push_back(StringRef(basePath));
+
+        // Scan all paths for GCC libraries.
+        for (const auto &GentooPath : GentooScanPaths) {
+          if (D.getVFS().exists(GentooPath + "/crtbegin.o")) {
+            if (!ScanGCCForMultilibs(TargetTriple, Args, GentooPath,
+                                     NeedsBiarchSuffix))
+              continue;
+
+            Version = GCCVersion::Parse(ActiveVersion.second);
+            GCCInstallPath = GentooPath;
+            GCCParentLibPath = std::string(GentooPath) + "/../../..";
+            GCCTriple.setTriple(ActiveVersion.first);
+            IsValid = true;
+            return true;
+          }
         }
       }
     }
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to