[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
This commit is contained in:
Qiu Chaofan 2022-03-24 16:58:58 +08:00
parent 1104d79261
commit d00e8400e2
12 changed files with 53 additions and 0 deletions

View File

@ -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>

View File

@ -149,6 +149,9 @@ public:
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;

View File

@ -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]>,

View File

@ -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))

View File

@ -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 different sysroot.

View File

@ -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

View File

@ -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"