[cfe-commits] [PATCH] [Driver] Make default GCC install prefix and sysroot relocatable

Kito Cheng kito at 0xlab.org
Mon Dec 10 22:45:08 PST 2012


Hi chapuni, chandlerc, rafael.espindola,

Make default GCC install prefix and sysroot relocatable, they are use absolute path now, so this patch can relocated the path if their prefix is install prefix (LLVM_PREFIX).

It's useful for build stand along toolchain, especially for build toolchain distribution:)

http://llvm-reviews.chandlerc.com/D203

Files:
  include/clang/Driver/Driver.h
  lib/Driver/Driver.cpp
  lib/Driver/ToolChains.cpp

Index: include/clang/Driver/Driver.h
===================================================================
--- include/clang/Driver/Driver.h
+++ include/clang/Driver/Driver.h
@@ -81,6 +81,9 @@
   /// sysroot, if present
   std::string SysRoot;
 
+  /// Default GCC install path
+  std::string DefaultGCCInstallPath;
+
   /// If the standard library is used
   bool UseStdLib;
 
@@ -197,6 +200,11 @@
   const std::string &getTitle() { return DriverTitle; }
   void setTitle(std::string Value) { DriverTitle = Value; }
 
+  /// \brief Get the default path of GCC install prefix
+  const char *getDefaultGCCInstallPath() const {
+    return DefaultGCCInstallPath.c_str();
+  }
+
   /// \brief Get the path to the main clang executable.
   const char *getClangProgramPath() const {
     return ClangExecutable.c_str();
Index: lib/Driver/Driver.cpp
===================================================================
--- lib/Driver/Driver.cpp
+++ lib/Driver/Driver.cpp
@@ -36,16 +36,26 @@
 // FIXME: It would prevent to include llvm-config.h
 // if it were included before system_error.h.
 #include "clang/Config/config.h"
+#include "llvm/Config/config.h" // for LLVM_PREFIX
 
 using namespace clang::driver;
 using namespace clang;
 
+static bool isPrefixFolderOf(StringRef prefix, StringRef path) {
+  bool IsEndWithBackslash = ((path.size() >= prefix.size()) &&
+                              path[prefix.size()] == '/') ||
+                            prefix[prefix.size()-1] == '/';
+  bool IsPrefix = path.startswith(prefix);
+  return (IsEndWithBackslash && IsPrefix) || prefix.equals(path);
+}
+
 Driver::Driver(StringRef ClangExecutable,
                StringRef DefaultTargetTriple,
                StringRef DefaultImageName,
                DiagnosticsEngine &Diags)
   : Opts(createDriverOptTable()), Diags(Diags),
     ClangExecutable(ClangExecutable), SysRoot(DEFAULT_SYSROOT),
+    DefaultGCCInstallPath(GCC_INSTALL_PREFIX),
     UseStdLib(true), DefaultTargetTriple(DefaultTargetTriple),
     DefaultImageName(DefaultImageName),
     DriverTitle("clang LLVM compiler"),
@@ -59,6 +69,33 @@
   Name = llvm::sys::path::stem(ClangExecutable);
   Dir  = llvm::sys::path::parent_path(ClangExecutable);
 
+  StringRef DefaultSysroot = DEFAULT_SYSROOT;
+  StringRef DefaultGCCInstallPathRef = GCC_INSTALL_PREFIX;
+  if (!DefaultSysroot.empty() || !DefaultGCCInstallPathRef.empty()) {
+    // Try to relocate the sysroot/gcc install path when prefix of
+    // ClangExecutable not equal to LLVM_PREFIX.
+    StringRef LLVMPrefix = LLVM_PREFIX;
+    if (!isPrefixFolderOf(LLVMPrefix, ClangExecutable)) {
+      // We only recognize the case for default sysroot/gcc install path is
+      // sub-folder of install prefix.
+      StringRef UpperFolder = "/../";
+      Twine RelocatedBase = Dir + UpperFolder;
+      if (isPrefixFolderOf(LLVMPrefix, SysRoot)) {
+        // Need relocate sysroot !
+        StringRef RelativePath = DefaultSysroot.data() + LLVMPrefix.size();
+        Twine RelocatedPath = RelocatedBase + RelativePath;
+        SysRoot = RelocatedPath.str();
+      }
+      if (isPrefixFolderOf(LLVMPrefix, DefaultGCCInstallPath)) {
+        // Need relocate default gcc install path !
+        StringRef RelativePath = DefaultGCCInstallPathRef.data() +
+                                 LLVMPrefix.size();
+        Twine RelocatedPath = RelocatedBase + RelativePath;
+        DefaultGCCInstallPath = RelocatedPath.str();
+      }
+    }
+  }
+
   // Compute the path to the resource directory.
   StringRef ClangResourceDir(CLANG_RESOURCE_DIR);
   SmallString<128> P(Dir);
Index: lib/Driver/ToolChains.cpp
===================================================================
--- lib/Driver/ToolChains.cpp
+++ lib/Driver/ToolChains.cpp
@@ -33,6 +33,7 @@
 // FIXME: This needs to be listed last until we fix the broken include guards
 // in these files and the LLVM config.h files.
 #include "clang/Config/config.h" // for GCC_INSTALL_PREFIX
+#include "llvm/Config/config.h" // for LLVM_PREFIX
 
 #include <cstdlib> // ::getenv
 
@@ -978,11 +979,11 @@
   return false;
 }
 
-static StringRef getGCCToolchainDir(const ArgList &Args) {
+static StringRef getGCCToolchainDir(const ArgList &Args, const Driver &D) {
   const Arg *A = Args.getLastArg(options::OPT_gcc_toolchain);
   if (A)
     return A->getValue();
-  return GCC_INSTALL_PREFIX;
+  return D.getDefaultGCCInstallPath();
 }
 
 /// \brief Construct a GCCInstallationDetector from the driver.
@@ -1017,7 +1018,7 @@
   SmallVector<std::string, 8> Prefixes(D.PrefixDirs.begin(),
                                        D.PrefixDirs.end());
 
-  StringRef GCCToolchainDir = getGCCToolchainDir(Args);
+  StringRef GCCToolchainDir = getGCCToolchainDir(Args, D);
   if (GCCToolchainDir != "") {
     if (GCCToolchainDir.back() == '/')
       GCCToolchainDir = GCCToolchainDir.drop_back(); // remove the /
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D203.1.patch
Type: text/x-patch
Size: 4872 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20121210/3a78a028/attachment.bin>


More information about the cfe-commits mailing list