mirror of
https://git.proxmox.com/git/llvm-toolchain
synced 2025-06-30 19:48:01 +00:00
207 lines
9.1 KiB
Diff
207 lines
9.1 KiB
Diff
hurd: find c++ headers
|
|
|
|
This should be factorized with Linux.cpp and the GNU/kFreeBSD case.
|
|
|
|
---
|
|
clang/lib/Driver/ToolChains/Hurd.cpp | 149 ++++++++++++++++++++++++++++++++++-
|
|
clang/lib/Driver/ToolChains/Hurd.h | 3
|
|
2 files changed, 148 insertions(+), 4 deletions(-)
|
|
|
|
--- a/clang/lib/Driver/ToolChains/Hurd.cpp
|
|
+++ b/clang/lib/Driver/ToolChains/Hurd.cpp
|
|
@@ -61,8 +61,20 @@ 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();
|
|
+ SelectedMultilib = GCCInstallation.getMultilib();
|
|
std::string SysRoot = computeSysRoot();
|
|
path_list &Paths = getFilePaths();
|
|
|
|
@@ -73,8 +85,61 @@ Hurd::Hurd(const Driver &D, const llvm::
|
|
ExtraOpts.push_back("--build-id");
|
|
#endif
|
|
|
|
- // If we are currently running Clang inside of the requested system root, add
|
|
- // its parent library paths to those searched.
|
|
+ // Add the multilib suffixed paths where they are available.
|
|
+ if (GCCInstallation.isValid()) {
|
|
+ const llvm::Triple &GCCTriple = GCCInstallation.getTriple();
|
|
+ const std::string &LibPath = GCCInstallation.getParentLibPath();
|
|
+
|
|
+ // Add toolchain / multilib specific file paths.
|
|
+ addMultilibsFilePaths(D, Multilibs, SelectedMultilib,
|
|
+ GCCInstallation.getInstallPath(), Paths);
|
|
+
|
|
+ // Sourcery CodeBench MIPS toolchain holds some libraries under
|
|
+ // a biarch-like suffix of the GCC installation.
|
|
+ addPathIfExists(
|
|
+ D, GCCInstallation.getInstallPath() + SelectedMultilib.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 + SelectedMultilib.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.
|
|
// 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)) {
|
|
@@ -88,8 +153,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))
|
|
@@ -156,6 +253,17 @@ 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);
|
|
+ }
|
|
+ }
|
|
+
|
|
if (getTriple().getArch() == llvm::Triple::x86) {
|
|
std::string Path = SysRoot + "/usr/include/i386-gnu";
|
|
if (D.getVFS().exists(Path))
|
|
@@ -174,3 +282,36 @@ void Hurd::addExtraOpts(llvm::opt::ArgSt
|
|
for (const auto &Opt : ExtraOpts)
|
|
CmdArgs.push_back(Opt.c_str());
|
|
}
|
|
+
|
|
+void Hurd::addLibStdCxxIncludePaths(const llvm::opt::ArgList &DriverArgs,
|
|
+ llvm::opt::ArgStringList &CC1Args) const {
|
|
+ // Try generic GCC detection first.
|
|
+ if (Generic_GCC::addGCCLibStdCxxIncludePaths(DriverArgs, CC1Args))
|
|
+ return;
|
|
+
|
|
+ // We need a detected GCC installation on Hurd to provide libstdc++'s
|
|
+ // headers.
|
|
+ if (!GCCInstallation.isValid())
|
|
+ return;
|
|
+
|
|
+ StringRef LibDir = GCCInstallation.getParentLibPath();
|
|
+ StringRef TripleStr = GCCInstallation.getTriple().str();
|
|
+ const Multilib &Multilib = GCCInstallation.getMultilib();
|
|
+ const GCCVersion &Version = GCCInstallation.getVersion();
|
|
+
|
|
+ const std::string LibStdCXXIncludePathCandidates[] = {
|
|
+ // 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;
|
|
+ }
|
|
+}
|
|
--- a/clang/lib/Driver/ToolChains/Hurd.h
|
|
+++ b/clang/lib/Driver/ToolChains/Hurd.h
|
|
@@ -26,6 +26,9 @@ public:
|
|
void
|
|
AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs,
|
|
llvm::opt::ArgStringList &CC1Args) const override;
|
|
+ void addLibStdCxxIncludePaths(
|
|
+ const llvm::opt::ArgList &DriverArgs,
|
|
+ llvm::opt::ArgStringList &CC1Args) const override;
|
|
|
|
std::string computeSysRoot() const;
|
|
|