mirror of
https://git.proxmox.com/git/llvm-toolchain
synced 2025-06-25 23:34:54 +00:00
282 lines
13 KiB
Diff
282 lines
13 KiB
Diff
This should be factorized with Linux.cpp and the GNU/kFreeBSD case.
|
|
|
|
Index: llvm-toolchain-7_7.0.1~svn347285/clang/lib/Driver/ToolChains/Hurd.cpp
|
|
===================================================================
|
|
--- llvm-toolchain-7_7.0.1~svn347285.orig/clang/lib/Driver/ToolChains/Hurd.cpp
|
|
+++ llvm-toolchain-7_7.0.1~svn347285/clang/lib/Driver/ToolChains/Hurd.cpp
|
|
@@ -67,15 +67,102 @@ static StringRef getOSLibDir(const llvm:
|
|
return Triple.isArch32Bit() ? "lib" : "lib64";
|
|
}
|
|
|
|
+static void addMultilibsFilePaths(const Driver &D, const MultilibSet &Multilibs,
|
|
+ const Multilib &Multilib,
|
|
+ StringRef InstallPath,
|
|
+ ToolChain::path_list &Paths) {
|
|
+ if (const auto &PathsCallback = Multilibs.filePathsCallback())
|
|
+ for (const auto &Path : PathsCallback(Multilib))
|
|
+ addPathIfExists(D, InstallPath + Path, Paths);
|
|
+}
|
|
+
|
|
Hurd::Hurd(const Driver &D, const llvm::Triple &Triple,
|
|
const ArgList &Args)
|
|
: Generic_ELF(D, Triple, Args) {
|
|
+ GCCInstallation.init(Triple, Args);
|
|
+ Multilibs = GCCInstallation.getMultilibs();
|
|
std::string SysRoot = computeSysRoot();
|
|
+
|
|
+ // Cross-compiling binutils and GCC installations (vanilla and openSUSE at
|
|
+ // least) put various tools in a triple-prefixed directory off of the parent
|
|
+ // of the GCC installation. We use the GCC triple here to ensure that we end
|
|
+ // up with tools that support the same amount of cross compiling as the
|
|
+ // detected GCC installation. For example, if we find a GCC installation
|
|
+ // targeting x86_64, but it is a bi-arch GCC installation, it can also be
|
|
+ // used to target i386.
|
|
+ // FIXME: This seems unlikely to be Linux- or Hurd-specific.
|
|
+ ToolChain::path_list &PPaths = getProgramPaths();
|
|
+ PPaths.push_back(Twine(GCCInstallation.getParentLibPath() + "/../" +
|
|
+ GCCInstallation.getTriple().str() + "/bin")
|
|
+ .str());
|
|
+
|
|
+#ifdef ENABLE_LINKER_BUILD_ID
|
|
+ ExtraOpts.push_back("--build-id");
|
|
+#endif
|
|
+
|
|
+ // The selection of paths to try here is designed to match the patterns which
|
|
+ // the GCC driver itself uses, as this is part of the GCC-compatible driver.
|
|
+ // This was determined by running GCC in a fake filesystem, creating all
|
|
+ // possible permutations of these directories, and seeing which ones it added
|
|
+ // to the link paths.
|
|
path_list &Paths = getFilePaths();
|
|
|
|
const std::string OSLibDir = getOSLibDir(Triple, Args);
|
|
const std::string MultiarchTriple = getMultiarchTriple(D, Triple, SysRoot);
|
|
|
|
+ // Add the multilib suffixed paths where they are available.
|
|
+ if (GCCInstallation.isValid()) {
|
|
+ const llvm::Triple &GCCTriple = GCCInstallation.getTriple();
|
|
+ const std::string &LibPath = GCCInstallation.getParentLibPath();
|
|
+ const Multilib &Multilib = GCCInstallation.getMultilib();
|
|
+ const MultilibSet &Multilibs = GCCInstallation.getMultilibs();
|
|
+
|
|
+ // Add toolchain / multilib specific file paths.
|
|
+ addMultilibsFilePaths(D, Multilibs, Multilib,
|
|
+ GCCInstallation.getInstallPath(), Paths);
|
|
+
|
|
+ // Sourcery CodeBench MIPS toolchain holds some libraries under
|
|
+ // a biarch-like suffix of the GCC installation.
|
|
+ addPathIfExists(D, GCCInstallation.getInstallPath() + Multilib.gccSuffix(),
|
|
+ Paths);
|
|
+
|
|
+ // GCC cross compiling toolchains will install target libraries which ship
|
|
+ // as part of the toolchain under <prefix>/<triple>/<libdir> rather than as
|
|
+ // any part of the GCC installation in
|
|
+ // <prefix>/<libdir>/gcc/<triple>/<version>. This decision is somewhat
|
|
+ // debatable, but is the reality today. We need to search this tree even
|
|
+ // when we have a sysroot somewhere else. It is the responsibility of
|
|
+ // whomever is doing the cross build targeting a sysroot using a GCC
|
|
+ // installation that is *not* within the system root to ensure two things:
|
|
+ //
|
|
+ // 1) Any DSOs that are linked in from this tree or from the install path
|
|
+ // above must be present on the system root and found via an
|
|
+ // appropriate rpath.
|
|
+ // 2) There must not be libraries installed into
|
|
+ // <prefix>/<triple>/<libdir> unless they should be preferred over
|
|
+ // those within the system root.
|
|
+ //
|
|
+ // Note that this matches the GCC behavior. See the below comment for where
|
|
+ // Clang diverges from GCC's behavior.
|
|
+ addPathIfExists(D, LibPath + "/../" + GCCTriple.str() + "/lib/../" +
|
|
+ OSLibDir + Multilib.osSuffix(),
|
|
+ Paths);
|
|
+
|
|
+ // If the GCC installation we found is inside of the sysroot, we want to
|
|
+ // prefer libraries installed in the parent prefix of the GCC installation.
|
|
+ // It is important to *not* use these paths when the GCC installation is
|
|
+ // outside of the system root as that can pick up unintended libraries.
|
|
+ // This usually happens when there is an external cross compiler on the
|
|
+ // host system, and a more minimal sysroot available that is the target of
|
|
+ // the cross. Note that GCC does include some of these directories in some
|
|
+ // configurations but this seems somewhere between questionable and simply
|
|
+ // a bug.
|
|
+ if (StringRef(LibPath).startswith(SysRoot)) {
|
|
+ addPathIfExists(D, LibPath + "/" + MultiarchTriple, Paths);
|
|
+ addPathIfExists(D, LibPath + "/../" + OSLibDir, Paths);
|
|
+ }
|
|
+ }
|
|
+
|
|
// Similar to the logic for GCC above, if we currently running Clang inside
|
|
// of the requested system root, add its parent library paths to
|
|
// those searched.
|
|
@@ -92,8 +179,40 @@ Hurd::Hurd(const Driver &D, const llvm::
|
|
addPathIfExists(D, SysRoot + "/usr/lib/" + MultiarchTriple, Paths);
|
|
addPathIfExists(D, SysRoot + "/usr/lib/../" + OSLibDir, Paths);
|
|
|
|
- // If we are currently running Clang inside of the requested system root, add
|
|
- // its parent library path to those searched.
|
|
+ // Try walking via the GCC triple path in case of biarch or multiarch GCC
|
|
+ // installations with strange symlinks.
|
|
+ if (GCCInstallation.isValid()) {
|
|
+ addPathIfExists(D,
|
|
+ SysRoot + "/usr/lib/" + GCCInstallation.getTriple().str() +
|
|
+ "/../../" + OSLibDir,
|
|
+ Paths);
|
|
+
|
|
+ // Add the 'other' biarch variant path
|
|
+ Multilib BiarchSibling;
|
|
+ if (GCCInstallation.getBiarchSibling(BiarchSibling)) {
|
|
+ addPathIfExists(D, GCCInstallation.getInstallPath() +
|
|
+ BiarchSibling.gccSuffix(),
|
|
+ Paths);
|
|
+ }
|
|
+
|
|
+ // See comments above on the multilib variant for details of why this is
|
|
+ // included even from outside the sysroot.
|
|
+ const std::string &LibPath = GCCInstallation.getParentLibPath();
|
|
+ const llvm::Triple &GCCTriple = GCCInstallation.getTriple();
|
|
+ const Multilib &Multilib = GCCInstallation.getMultilib();
|
|
+ addPathIfExists(D, LibPath + "/../" + GCCTriple.str() + "/lib" +
|
|
+ Multilib.osSuffix(),
|
|
+ Paths);
|
|
+
|
|
+ // See comments above on the multilib variant for details of why this is
|
|
+ // only included from within the sysroot.
|
|
+ if (StringRef(LibPath).startswith(SysRoot))
|
|
+ addPathIfExists(D, LibPath, Paths);
|
|
+ }
|
|
+
|
|
+ // Similar to the logic for GCC above, if we are currently running Clang
|
|
+ // inside of the requested system root, add its parent library path to those
|
|
+ // searched.
|
|
// FIXME: It's not clear whether we should use the driver's installed
|
|
// directory ('Dir' below) or the ResourceDir.
|
|
if (StringRef(D.Dir).startswith(SysRoot))
|
|
@@ -163,6 +282,16 @@ void Hurd::AddClangSystemIncludeArgs(con
|
|
// Lacking those, try to detect the correct set of system includes for the
|
|
// target triple.
|
|
|
|
+ // Add include directories specific to the selected multilib set and multilib.
|
|
+ if (GCCInstallation.isValid()) {
|
|
+ const auto &Callback = Multilibs.includeDirsCallback();
|
|
+ if (Callback) {
|
|
+ for (const auto &Path : Callback(GCCInstallation.getMultilib()))
|
|
+ addExternCSystemIncludeIfExists(
|
|
+ DriverArgs, CC1Args, GCCInstallation.getInstallPath() + Path);
|
|
+ }
|
|
+ }
|
|
+
|
|
const StringRef X86MultiarchIncludeDirs[] = {
|
|
"/usr/include/i386-gnu"};
|
|
|
|
@@ -189,3 +318,94 @@ void Hurd::AddClangSystemIncludeArgs(con
|
|
|
|
addExternCSystemInclude(DriverArgs, CC1Args, SysRoot + "/usr/include");
|
|
}
|
|
+
|
|
+static std::string DetectLibcxxIncludePath(StringRef base) {
|
|
+ std::error_code EC;
|
|
+ int MaxVersion = 0;
|
|
+ std::string MaxVersionString = "";
|
|
+ for (llvm::sys::fs::directory_iterator LI(base, EC), LE; !EC && LI != LE;
|
|
+ LI = LI.increment(EC)) {
|
|
+ StringRef VersionText = llvm::sys::path::filename(LI->path());
|
|
+ int Version;
|
|
+ if (VersionText[0] == 'v' &&
|
|
+ !VersionText.slice(1, StringRef::npos).getAsInteger(10, Version)) {
|
|
+ if (Version > MaxVersion) {
|
|
+ MaxVersion = Version;
|
|
+ MaxVersionString = VersionText;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ return MaxVersion ? (base + "/" + MaxVersionString).str() : "";
|
|
+}
|
|
+
|
|
+void Hurd::addLibCxxIncludePaths(const llvm::opt::ArgList &DriverArgs,
|
|
+ llvm::opt::ArgStringList &CC1Args) const {
|
|
+ const std::string& SysRoot = computeSysRoot();
|
|
+ const std::string LibCXXIncludePathCandidates[] = {
|
|
+ DetectLibcxxIncludePath(getDriver().ResourceDir + "/include/c++"),
|
|
+ DetectLibcxxIncludePath(getDriver().Dir + "/../include/c++"),
|
|
+ // If this is a development, non-installed, clang, libcxx will
|
|
+ // not be found at ../include/c++ but it likely to be found at
|
|
+ // one of the following two locations:
|
|
+ DetectLibcxxIncludePath(SysRoot + "/usr/local/include/c++"),
|
|
+ DetectLibcxxIncludePath(SysRoot + "/usr/include/c++") };
|
|
+ for (const auto &IncludePath : LibCXXIncludePathCandidates) {
|
|
+ if (IncludePath.empty() || !getVFS().exists(IncludePath))
|
|
+ continue;
|
|
+ // Use the first candidate that exists.
|
|
+ addSystemInclude(DriverArgs, CC1Args, IncludePath);
|
|
+ return;
|
|
+ }
|
|
+}
|
|
+
|
|
+void Hurd::addLibStdCxxIncludePaths(const llvm::opt::ArgList &DriverArgs,
|
|
+ llvm::opt::ArgStringList &CC1Args) const {
|
|
+ // We need a detected GCC installation on Hurd to provide libstdc++'s
|
|
+ // headers.
|
|
+ if (!GCCInstallation.isValid())
|
|
+ return;
|
|
+
|
|
+ // By default, look for the C++ headers in an include directory adjacent to
|
|
+ // the lib directory of the GCC installation. Note that this is expect to be
|
|
+ // equivalent to '/usr/include/c++/X.Y' in almost all cases.
|
|
+ StringRef LibDir = GCCInstallation.getParentLibPath();
|
|
+ StringRef InstallDir = GCCInstallation.getInstallPath();
|
|
+ StringRef TripleStr = GCCInstallation.getTriple().str();
|
|
+ const Multilib &Multilib = GCCInstallation.getMultilib();
|
|
+ const std::string GCCMultiarchTriple = getMultiarchTriple(
|
|
+ getDriver(), GCCInstallation.getTriple(), getDriver().SysRoot);
|
|
+ const std::string TargetMultiarchTriple =
|
|
+ getMultiarchTriple(getDriver(), getTriple(), getDriver().SysRoot);
|
|
+ const GCCVersion &Version = GCCInstallation.getVersion();
|
|
+
|
|
+ // The primary search for libstdc++ supports multiarch variants.
|
|
+ if (addLibStdCXXIncludePaths(LibDir.str() + "/../include",
|
|
+ "/c++/" + Version.Text, TripleStr,
|
|
+ GCCMultiarchTriple, TargetMultiarchTriple,
|
|
+ Multilib.includeSuffix(), DriverArgs, CC1Args))
|
|
+ return;
|
|
+
|
|
+ // Otherwise, fall back on a bunch of options which don't use multiarch
|
|
+ // layouts for simplicity.
|
|
+ const std::string LibStdCXXIncludePathCandidates[] = {
|
|
+ // Gentoo is weird and places its headers inside the GCC install,
|
|
+ // so if the first attempt to find the headers fails, try these patterns.
|
|
+ InstallDir.str() + "/include/g++-v" + Version.Text,
|
|
+ InstallDir.str() + "/include/g++-v" + Version.MajorStr + "." +
|
|
+ Version.MinorStr,
|
|
+ InstallDir.str() + "/include/g++-v" + Version.MajorStr,
|
|
+ // Android standalone toolchain has C++ headers in yet another place.
|
|
+ LibDir.str() + "/../" + TripleStr.str() + "/include/c++/" + Version.Text,
|
|
+ // Freescale SDK C++ headers are directly in <sysroot>/usr/include/c++,
|
|
+ // without a subdirectory corresponding to the gcc version.
|
|
+ LibDir.str() + "/../include/c++",
|
|
+ };
|
|
+
|
|
+ for (const auto &IncludePath : LibStdCXXIncludePathCandidates) {
|
|
+ if (addLibStdCXXIncludePaths(IncludePath, /*Suffix*/ "", TripleStr,
|
|
+ /*GCCMultiarchTriple*/ "",
|
|
+ /*TargetMultiarchTriple*/ "",
|
|
+ Multilib.includeSuffix(), DriverArgs, CC1Args))
|
|
+ break;
|
|
+ }
|
|
+}
|
|
Index: llvm-toolchain-7_7.0.1~svn347285/clang/lib/Driver/ToolChains/Hurd.h
|
|
===================================================================
|
|
--- llvm-toolchain-7_7.0.1~svn347285.orig/clang/lib/Driver/ToolChains/Hurd.h
|
|
+++ llvm-toolchain-7_7.0.1~svn347285/clang/lib/Driver/ToolChains/Hurd.h
|
|
@@ -27,6 +27,12 @@ public:
|
|
void
|
|
AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs,
|
|
llvm::opt::ArgStringList &CC1Args) const override;
|
|
+ void addLibCxxIncludePaths(
|
|
+ const llvm::opt::ArgList &DriverArgs,
|
|
+ llvm::opt::ArgStringList &CC1Args) const override;
|
|
+ void addLibStdCxxIncludePaths(
|
|
+ const llvm::opt::ArgList &DriverArgs,
|
|
+ llvm::opt::ArgStringList &CC1Args) const override;
|
|
|
|
virtual std::string computeSysRoot() const;
|
|
|