diff --git a/clang/docs/ClangCommandLineReference.rst b/clang/docs/ClangCommandLineReference.rst --- a/clang/docs/ClangCommandLineReference.rst +++ b/clang/docs/ClangCommandLineReference.rst @@ -515,6 +515,10 @@ Specify comma-separated list of offloading target triples (CUDA and HIP only) +.. option:: --overlay-platform-toolchain= + +Specify a toolchain with higher priority than sysroot in search paths. + .. option:: -p, --profile .. option:: -pagezero\_size diff --git a/clang/include/clang/Driver/Driver.h b/clang/include/clang/Driver/Driver.h --- a/clang/include/clang/Driver/Driver.h +++ b/clang/include/clang/Driver/Driver.h @@ -149,6 +149,9 @@ typedef SmallVector 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 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -4180,6 +4180,8 @@ def _output_class_directory : Separate<["--"], "output-class-directory">, Alias; def _output_EQ : Joined<["--"], "output=">, Alias; def _output : Separate<["--"], "output">, Alias; +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; 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 --- a/clang/lib/Driver/Driver.cpp +++ b/clang/lib/Driver/Driver.cpp @@ -1208,6 +1208,11 @@ 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 --- a/clang/lib/Driver/ToolChains/Gnu.cpp +++ b/clang/lib/Driver/ToolChains/Gnu.cpp @@ -1867,6 +1867,10 @@ 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 different sysroot. diff --git a/clang/lib/Driver/ToolChains/Linux.cpp b/clang/lib/Driver/ToolChains/Linux.cpp --- a/clang/lib/Driver/ToolChains/Linux.cpp +++ b/clang/lib/Driver/ToolChains/Linux.cpp @@ -260,6 +260,14 @@ 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 @@ 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 @@ 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 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 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 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 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 diff --git a/clang/test/Driver/overlay-toolchain.cpp b/clang/test/Driver/overlay-toolchain.cpp new file mode 100644 --- /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"