Author: Qiu Chaofan
Date: 2022-03-24T17:01:35+08:00
New Revision: d00e8400e2e3a602fdf40cd7348ed113952261d3

URL: 
https://github.com/llvm/llvm-project/commit/d00e8400e2e3a602fdf40cd7348ed113952261d3
DIFF: 
https://github.com/llvm/llvm-project/commit/d00e8400e2e3a602fdf40cd7348ed113952261d3.diff

LOG: [Clang] Add option to set alternative toolchain path

In some cases, we need to set alternative toolchain path other than the
default with system (headers, libraries, dynamic linker prefix, ld path,
etc.), e.g., to pick up newer components, but keep sysroot at the same
time (to pick up extra packages).

This change introduces a new option --overlay-platform-toolchain to set
up such alternative toolchain path.

Reviewed By: hubert.reinterpretcast

Differential Revision: https://reviews.llvm.org/D121992

Added: 
    clang/test/Driver/Inputs/powerpc64le-linux-gnu-tree/gcc-11.2.0/include/.keep
    clang/test/Driver/Inputs/powerpc64le-linux-gnu-tree/gcc-11.2.0/lib64/.keep
    clang/test/Driver/Inputs/powerpc64le-linux-gnu-tree/gcc-8.3.0/include/.keep
    
clang/test/Driver/Inputs/powerpc64le-linux-gnu-tree/gcc-8.3.0/lib/gcc/powerpc64le-linux-gnu/8.3.0/.keep
    clang/test/Driver/Inputs/powerpc64le-linux-gnu-tree/gcc-8.3.0/lib64/.keep
    clang/test/Driver/overlay-toolchain.cpp

Modified: 
    clang/docs/ClangCommandLineReference.rst
    clang/include/clang/Driver/Driver.h
    clang/include/clang/Driver/Options.td
    clang/lib/Driver/Driver.cpp
    clang/lib/Driver/ToolChains/Gnu.cpp
    clang/lib/Driver/ToolChains/Linux.cpp

Removed: 
    


################################################################################
diff  --git a/clang/docs/ClangCommandLineReference.rst 
b/clang/docs/ClangCommandLineReference.rst
index 9d097ccae6aab..d226ab75b3288 100644
--- a/clang/docs/ClangCommandLineReference.rst
+++ b/clang/docs/ClangCommandLineReference.rst
@@ -515,6 +515,10 @@ CUDA offloading device architecture (e.g. sm\_35), or HIP 
offloading target ID i
 
 Specify comma-separated list of offloading target triples (CUDA and HIP only)
 
+.. option:: --overlay-platform-toolchain=<arg>
+
+Specify a toolchain with higher priority than sysroot in search paths.
+
 .. option:: -p, --profile
 
 .. option:: -pagezero\_size<arg>

diff  --git a/clang/include/clang/Driver/Driver.h 
b/clang/include/clang/Driver/Driver.h
index 6f24f649ea544..50aa7bea8f6d5 100644
--- a/clang/include/clang/Driver/Driver.h
+++ b/clang/include/clang/Driver/Driver.h
@@ -149,6 +149,9 @@ class Driver {
   typedef SmallVector<std::string, 4> prefix_list;
   prefix_list PrefixDirs;
 
+  /// Alternative toolchain path used prior to sysroot.
+  std::string OverlayToolChainPath;
+
   /// sysroot, if present
   std::string SysRoot;
 

diff  --git a/clang/include/clang/Driver/Options.td 
b/clang/include/clang/Driver/Options.td
index 114b230b39e8f..c63c02bb8941a 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -4180,6 +4180,8 @@ def _output_class_directory_EQ : Joined<["--"], 
"output-class-directory=">, Alia
 def _output_class_directory : Separate<["--"], "output-class-directory">, 
Alias<foutput_class_dir_EQ>;
 def _output_EQ : Joined<["--"], "output=">, Alias<o>;
 def _output : Separate<["--"], "output">, Alias<o>;
+def _overlay_platform_toolchain_EQ : Joined<["--"], 
"overlay-platform-toolchain=">;
+def _overlay_platform_toolchain : Separate<["--"], 
"overlay-platform-toolchain">, Alias<_overlay_platform_toolchain_EQ>;
 def _param : Separate<["--"], "param">, Group<CompileOnly_Group>;
 def _param_EQ : Joined<["--"], "param=">, Alias<_param>;
 def _precompile : Flag<["--"], "precompile">, Flags<[NoXarchOption]>,

diff  --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp
index 44a89e9e26ee1..31ef07cd5acc6 100644
--- a/clang/lib/Driver/Driver.cpp
+++ b/clang/lib/Driver/Driver.cpp
@@ -1208,6 +1208,11 @@ Compilation *Driver::BuildCompilation(ArrayRef<const 
char *> ArgList) {
       CompilerPath = Split.second;
     }
   }
+  if (const Arg *A =
+          Args.getLastArg(options::OPT__overlay_platform_toolchain_EQ)) {
+    OverlayToolChainPath = A->getValue();
+    DyldPrefix = A->getValue();
+  }
   if (const Arg *A = Args.getLastArg(options::OPT__sysroot_EQ))
     SysRoot = A->getValue();
   if (const Arg *A = Args.getLastArg(options::OPT__dyld_prefix_EQ))

diff  --git a/clang/lib/Driver/ToolChains/Gnu.cpp 
b/clang/lib/Driver/ToolChains/Gnu.cpp
index bb3cba6dc4f77..7164f42170a8c 100644
--- a/clang/lib/Driver/ToolChains/Gnu.cpp
+++ b/clang/lib/Driver/ToolChains/Gnu.cpp
@@ -1867,6 +1867,10 @@ static llvm::StringRef getGCCToolchainDir(const ArgList 
&Args,
   if (A)
     return A->getValue();
 
+  if (const Arg *X = Args.getLastArg(
+          clang::driver::options::OPT__overlay_platform_toolchain_EQ))
+    return X->getValue();
+
   // If we have a SysRoot, ignore GCC_INSTALL_PREFIX.
   // GCC_INSTALL_PREFIX specifies the gcc installation for the default
   // sysroot and is likely not valid with a 
diff erent sysroot.

diff  --git a/clang/lib/Driver/ToolChains/Linux.cpp 
b/clang/lib/Driver/ToolChains/Linux.cpp
index f85c04df4f6c9..c5393b6f42d3f 100644
--- a/clang/lib/Driver/ToolChains/Linux.cpp
+++ b/clang/lib/Driver/ToolChains/Linux.cpp
@@ -260,6 +260,14 @@ Linux::Linux(const Driver &D, const llvm::Triple &Triple, 
const ArgList &Args)
 
   const std::string OSLibDir = std::string(getOSLibDir(Triple, Args));
   const std::string MultiarchTriple = getMultiarchTriple(D, Triple, SysRoot);
+  const std::string &ExtraPath = D.OverlayToolChainPath;
+
+  if (!D.OverlayToolChainPath.empty()) {
+    addPathIfExists(D, ExtraPath + "/lib/" + MultiarchTriple, Paths);
+    addPathIfExists(D, ExtraPath + "/lib/../" + OSLibDir, Paths);
+    addPathIfExists(D, ExtraPath + "/usr/lib/" + MultiarchTriple, Paths);
+    addPathIfExists(D, ExtraPath + "/usr/lib/../" + OSLibDir, Paths);
+  }
 
   // mips32: Debian multilib, we use /libo32, while in other case, /lib is
   // used. We need add both libo32 and /lib.
@@ -314,6 +322,11 @@ Linux::Linux(const Driver &D, const llvm::Triple &Triple, 
const ArgList &Args)
       addPathIfExists(D, D.Dir + "/../" + OSLibDir, Paths);
   }
 
+  if (!D.OverlayToolChainPath.empty()) {
+    addPathIfExists(D, ExtraPath + "/lib", Paths);
+    addPathIfExists(D, ExtraPath + "/usr/lib", Paths);
+  }
+
   addPathIfExists(D, SysRoot + "/lib", Paths);
   addPathIfExists(D, SysRoot + "/usr/lib", Paths);
 }
@@ -567,6 +580,10 @@ void Linux::AddClangSystemIncludeArgs(const ArgList 
&DriverArgs,
   if (DriverArgs.hasArg(options::OPT_nostdlibinc))
     return;
 
+  if (!D.OverlayToolChainPath.empty())
+    addExternCSystemInclude(DriverArgs, CC1Args,
+                            D.OverlayToolChainPath + "/include");
+
   // LOCAL_INCLUDE_DIR
   addSystemInclude(DriverArgs, CC1Args, SysRoot + "/usr/local/include");
   // TOOL_INCLUDE_DIR

diff  --git 
a/clang/test/Driver/Inputs/powerpc64le-linux-gnu-tree/gcc-11.2.0/include/.keep 
b/clang/test/Driver/Inputs/powerpc64le-linux-gnu-tree/gcc-11.2.0/include/.keep
new file mode 100644
index 0000000000000..e69de29bb2d1d

diff  --git 
a/clang/test/Driver/Inputs/powerpc64le-linux-gnu-tree/gcc-11.2.0/lib64/.keep 
b/clang/test/Driver/Inputs/powerpc64le-linux-gnu-tree/gcc-11.2.0/lib64/.keep
new file mode 100644
index 0000000000000..e69de29bb2d1d

diff  --git 
a/clang/test/Driver/Inputs/powerpc64le-linux-gnu-tree/gcc-8.3.0/include/.keep 
b/clang/test/Driver/Inputs/powerpc64le-linux-gnu-tree/gcc-8.3.0/include/.keep
new file mode 100644
index 0000000000000..e69de29bb2d1d

diff  --git 
a/clang/test/Driver/Inputs/powerpc64le-linux-gnu-tree/gcc-8.3.0/lib/gcc/powerpc64le-linux-gnu/8.3.0/.keep
 
b/clang/test/Driver/Inputs/powerpc64le-linux-gnu-tree/gcc-8.3.0/lib/gcc/powerpc64le-linux-gnu/8.3.0/.keep
new file mode 100644
index 0000000000000..e69de29bb2d1d

diff  --git 
a/clang/test/Driver/Inputs/powerpc64le-linux-gnu-tree/gcc-8.3.0/lib64/.keep 
b/clang/test/Driver/Inputs/powerpc64le-linux-gnu-tree/gcc-8.3.0/lib64/.keep
new file mode 100644
index 0000000000000..e69de29bb2d1d

diff  --git a/clang/test/Driver/overlay-toolchain.cpp 
b/clang/test/Driver/overlay-toolchain.cpp
new file mode 100644
index 0000000000000..074180220e72e
--- /dev/null
+++ b/clang/test/Driver/overlay-toolchain.cpp
@@ -0,0 +1,18 @@
+// RUN: %clangxx %s -### --target=powerpc64le-linux-gnu \
+// RUN:   
--overlay-platform-toolchain=%S/Inputs/powerpc64le-linux-gnu-tree/gcc-11.2.0 \
+// RUN:   2>&1 | FileCheck %s --check-prefix=OVERLAY
+// RUN: %clangxx %s -### --target=powerpc64le-linux-gnu \
+// RUN:   --sysroot=%S/Inputs/powerpc64le-linux-gnu-tree/gcc-8.3.0 \
+// RUN:   
--overlay-platform-toolchain=%S/Inputs/powerpc64le-linux-gnu-tree/gcc-11.2.0 \
+// RUN:   2>&1 | FileCheck %s --check-prefixes=OVERLAY,ROOT
+
+// OVERLAY: "-internal-externc-isystem"
+// OVERLAY: "[[TOOLCHAIN:[^"]+]]/powerpc64le-linux-gnu-tree/gcc-11.2.0/include"
+// ROOT: "-internal-externc-isystem"
+// ROOT: "[[TOOLCHAIN]]/powerpc64le-linux-gnu-tree/gcc-8.3.0/include"
+// OVERLAY: "-dynamic-linker"
+// OVERLAY: 
"[[TOOLCHAIN]]/powerpc64le-linux-gnu-tree/gcc-11.2.0/lib64/ld64.so.2"
+// OVERLAY: 
"-L[[TOOLCHAIN]]/powerpc64le-linux-gnu-tree/gcc-11.2.0/lib/../lib64"
+// ROOT: "-L[[TOOLCHAIN]]/powerpc64le-linux-gnu-tree/gcc-8.3.0/lib/../lib64"
+// OVERLAY: "-L[[TOOLCHAIN]]/powerpc64le-linux-gnu-tree/gcc-11.2.0/lib"
+// ROOT: "-L[[TOOLCHAIN]]/powerpc64le-linux-gnu-tree/gcc-8.3.0/lib"


        
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to