https://github.com/CendioOssman created https://github.com/llvm/llvm-project/pull/155219
Various fixes to make sure clang can find libstdc++ headers and library for current versions of gcc. Tested with a cross-compiler setup, but should hopefully work correctly for a native setup as well. Also adds support for statically linking libstdc++ and libgcc_s. >From 4a3af37be0c4aad6bf0a35c7a236a8364fbd4aa6 Mon Sep 17 00:00:00 2001 From: Pierre Ossman <oss...@cendio.se> Date: Thu, 21 Aug 2025 09:51:53 +0200 Subject: [PATCH 1/7] Allow subclass override of libstdc+++ for Darwin --- clang/lib/Driver/ToolChains/Darwin.cpp | 68 +++++++++++++++----------- clang/lib/Driver/ToolChains/Darwin.h | 6 +++ 2 files changed, 45 insertions(+), 29 deletions(-) diff --git a/clang/lib/Driver/ToolChains/Darwin.cpp b/clang/lib/Driver/ToolChains/Darwin.cpp index 234683f2f4882..9d5c1854f194b 100644 --- a/clang/lib/Driver/ToolChains/Darwin.cpp +++ b/clang/lib/Driver/ToolChains/Darwin.cpp @@ -2848,39 +2848,49 @@ void AppleMachO::AddCXXStdlibLibArgs(const ArgList &Args, break; case ToolChain::CST_Libstdcxx: - // Unfortunately, -lstdc++ doesn't always exist in the standard search path; - // it was previously found in the gcc lib dir. However, for all the Darwin - // platforms we care about it was -lstdc++.6, so we search for that - // explicitly if we can't see an obvious -lstdc++ candidate. - - // Check in the sysroot first. - if (const Arg *A = Args.getLastArg(options::OPT_isysroot)) { - SmallString<128> P(A->getValue()); - llvm::sys::path::append(P, "usr", "lib", "libstdc++.dylib"); - - if (!getVFS().exists(P)) { - llvm::sys::path::remove_filename(P); - llvm::sys::path::append(P, "libstdc++.6.dylib"); - if (getVFS().exists(P)) { - CmdArgs.push_back(Args.MakeArgString(P)); - return; - } - } - } + AddGnuCPlusPlusStdlibLibArgs(Args, CmdArgs); + break; + } +} - // Otherwise, look in the root. - // FIXME: This should be removed someday when we don't have to care about - // 10.6 and earlier, where /usr/lib/libstdc++.dylib does not exist. - if (!getVFS().exists("/usr/lib/libstdc++.dylib") && - getVFS().exists("/usr/lib/libstdc++.6.dylib")) { - CmdArgs.push_back("/usr/lib/libstdc++.6.dylib"); - return; +void AppleMachO::AddGnuCPlusPlusStdlibLibArgs( + const ArgList &Args, ArgStringList &CmdArgs) const { + CmdArgs.push_back("-lstdc++"); +} + +void DarwinClang::AddGnuCPlusPlusStdlibLibArgs( + const ArgList &Args, ArgStringList &CmdArgs) const { + // Unfortunately, -lstdc++ doesn't always exist in the standard search path; + // it was previously found in the gcc lib dir. However, for all the Darwin + // platforms we care about it was -lstdc++.6, so we search for that + // explicitly if we can't see an obvious -lstdc++ candidate. + + // Check in the sysroot first. + if (const Arg *A = Args.getLastArg(options::OPT_isysroot)) { + SmallString<128> P(A->getValue()); + llvm::sys::path::append(P, "usr", "lib", "libstdc++.dylib"); + + if (!getVFS().exists(P)) { + llvm::sys::path::remove_filename(P); + llvm::sys::path::append(P, "libstdc++.6.dylib"); + if (getVFS().exists(P)) { + CmdArgs.push_back(Args.MakeArgString(P)); + return; + } } + } - // Otherwise, let the linker search. - CmdArgs.push_back("-lstdc++"); - break; + // Otherwise, look in the root. + // FIXME: This should be removed someday when we don't have to care about + // 10.6 and earlier, where /usr/lib/libstdc++.dylib does not exist. + if (!getVFS().exists("/usr/lib/libstdc++.dylib") && + getVFS().exists("/usr/lib/libstdc++.6.dylib")) { + CmdArgs.push_back("/usr/lib/libstdc++.6.dylib"); + return; } + + // Otherwise, let the linker search. + CmdArgs.push_back("-lstdc++"); } void DarwinClang::AddCCKextLibArgs(const ArgList &Args, diff --git a/clang/lib/Driver/ToolChains/Darwin.h b/clang/lib/Driver/ToolChains/Darwin.h index d1cfb6f4a5bf7..3cefe489f7cf4 100644 --- a/clang/lib/Driver/ToolChains/Darwin.h +++ b/clang/lib/Driver/ToolChains/Darwin.h @@ -338,6 +338,9 @@ class LLVM_LIBRARY_VISIBILITY AppleMachO : public MachO { virtual void AddGnuCPlusPlusIncludePaths(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args) const; + virtual void + AddGnuCPlusPlusStdlibLibArgs(const llvm::opt::ArgList &Args, + llvm::opt::ArgStringList &CmdArgs) const; }; /// Darwin - The base Darwin tool chain. @@ -689,6 +692,9 @@ class LLVM_LIBRARY_VISIBILITY DarwinClang : public Darwin { void AddGnuCPlusPlusIncludePaths(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args) const override; + void + AddGnuCPlusPlusStdlibLibArgs(const llvm::opt::ArgList &Args, + llvm::opt::ArgStringList &CmdArgs) const override; bool AddGnuCPlusPlusIncludePaths(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args, >From 14fd23364a4627dad541dd84cd7f211fcc9de14e Mon Sep 17 00:00:00 2001 From: Pierre Ossman <oss...@cendio.se> Date: Thu, 21 Aug 2025 10:03:10 +0200 Subject: [PATCH 2/7] Fix sysroot handling for libstdc++ for Darwin --- clang/lib/Driver/ToolChains/Darwin.cpp | 29 ++++++++------------------ 1 file changed, 9 insertions(+), 20 deletions(-) diff --git a/clang/lib/Driver/ToolChains/Darwin.cpp b/clang/lib/Driver/ToolChains/Darwin.cpp index 9d5c1854f194b..afac7c7ff35a9 100644 --- a/clang/lib/Driver/ToolChains/Darwin.cpp +++ b/clang/lib/Driver/ToolChains/Darwin.cpp @@ -2865,31 +2865,20 @@ void DarwinClang::AddGnuCPlusPlusStdlibLibArgs( // platforms we care about it was -lstdc++.6, so we search for that // explicitly if we can't see an obvious -lstdc++ candidate. - // Check in the sysroot first. - if (const Arg *A = Args.getLastArg(options::OPT_isysroot)) { - SmallString<128> P(A->getValue()); - llvm::sys::path::append(P, "usr", "lib", "libstdc++.dylib"); - - if (!getVFS().exists(P)) { - llvm::sys::path::remove_filename(P); - llvm::sys::path::append(P, "libstdc++.6.dylib"); - if (getVFS().exists(P)) { - CmdArgs.push_back(Args.MakeArgString(P)); - return; - } - } - } + llvm::SmallString<128> UsrLibStdCxx = GetEffectiveSysroot(Args); + llvm::sys::path::append(UsrLibStdCxx, "usr", "lib", "libstdc++.dylib"); - // Otherwise, look in the root. // FIXME: This should be removed someday when we don't have to care about // 10.6 and earlier, where /usr/lib/libstdc++.dylib does not exist. - if (!getVFS().exists("/usr/lib/libstdc++.dylib") && - getVFS().exists("/usr/lib/libstdc++.6.dylib")) { - CmdArgs.push_back("/usr/lib/libstdc++.6.dylib"); - return; + if (!getVFS().exists(UsrLibStdCxx)) { + llvm::sys::path::remove_filename(UsrLibStdCxx); + llvm::sys::path::append(UsrLibStdCxx, "libstdc++.6.dylib"); + if (getVFS().exists(UsrLibStdCxx)) { + CmdArgs.push_back(Args.MakeArgString(UsrLibStdCxx)); + return; + } } - // Otherwise, let the linker search. CmdArgs.push_back("-lstdc++"); } >From e731838f4473a1fa044f13bc9eb7f6e3e20caaf8 Mon Sep 17 00:00:00 2001 From: Pierre Ossman <oss...@cendio.se> Date: Thu, 21 Aug 2025 10:39:11 +0200 Subject: [PATCH 3/7] Allow gcc detection on Darwin systems --- clang/lib/Driver/ToolChains/Gnu.cpp | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/clang/lib/Driver/ToolChains/Gnu.cpp b/clang/lib/Driver/ToolChains/Gnu.cpp index 01b146db24f3e..e6f9452bc163b 100644 --- a/clang/lib/Driver/ToolChains/Gnu.cpp +++ b/clang/lib/Driver/ToolChains/Gnu.cpp @@ -1864,9 +1864,11 @@ static bool findBiarchMultilibs(const Driver &D, .flag("-m64", /*Disallow=*/true) .makeMultilib(); - // GCC toolchain for IAMCU doesn't have crtbegin.o, so look for libgcc.a. + // GCC toolchain for IAMCU and Darwin doesn't have crtbegin.o, so look for libgcc.a. FilterNonExistent NonExistent( - Path, TargetTriple.isOSIAMCU() ? "/libgcc.a" : "/crtbegin.o", D.getVFS()); + Path, + (TargetTriple.isOSIAMCU() || TargetTriple.isOSDarwin()) ? "/libgcc.a" : "/crtbegin.o", + D.getVFS()); // Determine default multilib from: 32, 64, x32 // Also handle cases such as 64 on 32, 32 on 64, etc. @@ -2556,6 +2558,11 @@ void Generic_GCC::GCCInstallationDetector::AddDefaultGCCPrefixes( return; } + if (TargetTriple.isOSDarwin()) { + LibDirs.push_back("/lib"); + return; + } + switch (TargetTriple.getArch()) { case llvm::Triple::aarch64: LibDirs.append(begin(AArch64LibDirs), end(AArch64LibDirs)); >From e2743ef5f174ae4d742b3b3ad6377f667d7ad7cd Mon Sep 17 00:00:00 2001 From: Pierre Ossman <oss...@cendio.se> Date: Thu, 21 Aug 2025 10:57:43 +0200 Subject: [PATCH 4/7] Always look for distribution supplied gcc A cross compiling gcc is generally installed outside of the sysroot, so we should always search the root system for our desired triple. --- clang/lib/Driver/ToolChains/Gnu.cpp | 6 ++---- clang/test/Driver/pic.c | 4 ++-- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/clang/lib/Driver/ToolChains/Gnu.cpp b/clang/lib/Driver/ToolChains/Gnu.cpp index e6f9452bc163b..1d17fb6753bd9 100644 --- a/clang/lib/Driver/ToolChains/Gnu.cpp +++ b/clang/lib/Driver/ToolChains/Gnu.cpp @@ -2163,10 +2163,8 @@ void Generic_GCC::GCCInstallationDetector::init( // Next, look for prefix(es) that correspond to distribution-supplied gcc // installations. - if (D.SysRoot.empty()) { - // Typically /usr. - AddDefaultGCCPrefixes(TargetTriple, Prefixes, D.SysRoot); - } + // Typically /usr. + AddDefaultGCCPrefixes(TargetTriple, Prefixes, ""); // Try to respect gcc-config on Gentoo if --gcc-toolchain is not provided. // This avoids accidentally enforcing the system GCC version when using a diff --git a/clang/test/Driver/pic.c b/clang/test/Driver/pic.c index f5d0745422790..24bc26937dda3 100644 --- a/clang/test/Driver/pic.c +++ b/clang/test/Driver/pic.c @@ -26,8 +26,8 @@ // // CHECK-PIE-LD: "{{.*}}ld{{(.exe)?}}" // CHECK-PIE-LD: "-pie" -// CHECK-PIE-LD: "Scrt1.o" "crti.o" "crtbeginS.o" -// CHECK-PIE-LD: "crtendS.o" "crtn.o" +// CHECK-PIE-LD: "Scrt1.o" "crti.o" "{{.*}}crtbeginS.o" +// CHECK-PIE-LD: "{{.*}}crtendS.o" "crtn.o" // // CHECK-NOPIE-LD: "-nopie" // >From b6667b3d397eb0c17eb25aad91258eab68f1b3d6 Mon Sep 17 00:00:00 2001 From: Pierre Ossman <oss...@cendio.se> Date: Thu, 21 Aug 2025 12:53:07 +0200 Subject: [PATCH 5/7] Respect added library paths for Darwin toolchain --- clang/lib/Driver/ToolChains/Darwin.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/clang/lib/Driver/ToolChains/Darwin.cpp b/clang/lib/Driver/ToolChains/Darwin.cpp index afac7c7ff35a9..f4921dba9fd6d 100644 --- a/clang/lib/Driver/ToolChains/Darwin.cpp +++ b/clang/lib/Driver/ToolChains/Darwin.cpp @@ -681,6 +681,8 @@ void darwin::Linker::ConstructJob(Compilation &C, const JobAction &JA, Args.AddAllArgs(CmdArgs, options::OPT_L); + getToolChain().AddFilePathLibArgs(Args, CmdArgs); + AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs, JA); // Build the input file for -filelist (list of linker input files) in case we // need it later >From 079c4ef6777300b469c35aa809a39b5bf5f204bd Mon Sep 17 00:00:00 2001 From: Pierre Ossman <oss...@cendio.se> Date: Thu, 21 Aug 2025 11:00:45 +0200 Subject: [PATCH 6/7] Find proper gcc installations for Darwin --- clang/lib/Driver/ToolChains/Darwin.cpp | 109 +++++++++++++++++++++---- clang/lib/Driver/ToolChains/Darwin.h | 11 +++ 2 files changed, 103 insertions(+), 17 deletions(-) diff --git a/clang/lib/Driver/ToolChains/Darwin.cpp b/clang/lib/Driver/ToolChains/Darwin.cpp index f4921dba9fd6d..6fde8cf931fa5 100644 --- a/clang/lib/Driver/ToolChains/Darwin.cpp +++ b/clang/lib/Driver/ToolChains/Darwin.cpp @@ -1179,7 +1179,31 @@ Tool *MachO::buildAssembler() const { DarwinClang::DarwinClang(const Driver &D, const llvm::Triple &Triple, const ArgList &Args) - : Darwin(D, Triple, Args) {} + : Darwin(D, Triple, Args), GCCInstallation(D) { + GCCInstallation.init(Triple, Args); + if (GCCInstallation.isValid()) { + StringRef LibDir = GCCInstallation.getParentLibPath(); + StringRef TripleStr = GCCInstallation.getTriple().str(); + const Generic_GCC::GCCVersion &Version = GCCInstallation.getVersion(); + + std::string Path; + + // Try /gcc/$triple/$version/ + Path = LibDir.str() + "/gcc/" + TripleStr.str() + "/" + Version.Text; + if (getVFS().exists(Path)) + getFilePaths().push_back(Path); + + // Try /gcc/$triple/lib/ + Path = LibDir.str() + "/gcc/" + TripleStr.str() + "/lib"; + if (getVFS().exists(Path)) + getFilePaths().push_back(Path); + + // Try /../$triple/lib/ + Path = LibDir.str() + "/../" + TripleStr.str() + "/lib"; + if (getVFS().exists(Path)) + getFilePaths().push_back(Path); + } +} void DarwinClang::addClangWarningOptions(ArgStringList &CC1Args) const { // Always error about undefined 'TARGET_OS_*' macros. @@ -2795,9 +2819,52 @@ void AppleMachO::AddGnuCPlusPlusIncludePaths( const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args) const {} +bool DarwinClang::addLibStdCXXIncludePaths(Twine IncludeDir, StringRef Triple, + const llvm::opt::ArgList &DriverArgs, + llvm::opt::ArgStringList &CC1Args) const { + if (!getVFS().exists(IncludeDir)) + return false; + + // GPLUSPLUS_INCLUDE_DIR + addSystemInclude(DriverArgs, CC1Args, IncludeDir); + // GPLUSPLUS_TOOL_INCLUDE_DIR + addSystemInclude(DriverArgs, CC1Args, IncludeDir + "/" + Triple); + // GPLUSPLUS_BACKWARD_INCLUDE_DIR + addSystemInclude(DriverArgs, CC1Args, IncludeDir + "/backward"); + + return true; +} + void DarwinClang::AddGnuCPlusPlusIncludePaths( const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args) const { + if (GCCInstallation.isValid()) { + // This is a stripped down version of Generic_GCC::addGCCLibStdCxxIncludePaths. + StringRef LibDir = GCCInstallation.getParentLibPath(); + StringRef TripleStr = GCCInstallation.getTriple().str(); + const Generic_GCC::GCCVersion &Version = GCCInstallation.getVersion(); + + // Try /../$triple/include/c++/$version + if (addLibStdCXXIncludePaths( + LibDir.str() + "/../" + TripleStr + "/include/c++/" + Version.Text, + TripleStr, DriverArgs, CC1Args)) + return; + + // Try /gcc/$triple/$version/include/c++/ + if (addLibStdCXXIncludePaths(LibDir.str() + "/gcc/" + TripleStr + "/" + + Version.Text + "/include/c++/", + TripleStr, DriverArgs, CC1Args)) + return; + + // Try /../include/c++/$version + if (addLibStdCXXIncludePaths(LibDir.str() + "/../include/c++/" + Version.Text, + TripleStr, DriverArgs, CC1Args)) + return; + + getDriver().Diag(diag::warn_drv_libstdcxx_not_found); + return; + } + llvm::SmallString<128> UsrIncludeCxx = GetEffectiveSysroot(DriverArgs); llvm::sys::path::append(UsrIncludeCxx, "usr", "include", "c++"); @@ -2862,22 +2929,24 @@ void AppleMachO::AddGnuCPlusPlusStdlibLibArgs( void DarwinClang::AddGnuCPlusPlusStdlibLibArgs( const ArgList &Args, ArgStringList &CmdArgs) const { - // Unfortunately, -lstdc++ doesn't always exist in the standard search path; - // it was previously found in the gcc lib dir. However, for all the Darwin - // platforms we care about it was -lstdc++.6, so we search for that - // explicitly if we can't see an obvious -lstdc++ candidate. - - llvm::SmallString<128> UsrLibStdCxx = GetEffectiveSysroot(Args); - llvm::sys::path::append(UsrLibStdCxx, "usr", "lib", "libstdc++.dylib"); - - // FIXME: This should be removed someday when we don't have to care about - // 10.6 and earlier, where /usr/lib/libstdc++.dylib does not exist. - if (!getVFS().exists(UsrLibStdCxx)) { - llvm::sys::path::remove_filename(UsrLibStdCxx); - llvm::sys::path::append(UsrLibStdCxx, "libstdc++.6.dylib"); - if (getVFS().exists(UsrLibStdCxx)) { - CmdArgs.push_back(Args.MakeArgString(UsrLibStdCxx)); - return; + if (!GCCInstallation.isValid()) { + // Unfortunately, -lstdc++ doesn't always exist in the standard search path; + // it was previously found in the gcc lib dir. However, for all the Darwin + // platforms we care about it was -lstdc++.6, so we search for that + // explicitly if we can't see an obvious -lstdc++ candidate. + + llvm::SmallString<128> UsrLibStdCxx = GetEffectiveSysroot(Args); + llvm::sys::path::append(UsrLibStdCxx, "usr", "lib", "libstdc++.dylib"); + + // FIXME: This should be removed someday when we don't have to care about + // 10.6 and earlier, where /usr/lib/libstdc++.dylib does not exist. + if (!getVFS().exists(UsrLibStdCxx)) { + llvm::sys::path::remove_filename(UsrLibStdCxx); + llvm::sys::path::append(UsrLibStdCxx, "libstdc++.6.dylib"); + if (getVFS().exists(UsrLibStdCxx)) { + CmdArgs.push_back(Args.MakeArgString(UsrLibStdCxx)); + return; + } } } @@ -3786,3 +3855,9 @@ void AppleMachO::printVerboseInfo(raw_ostream &OS) const { CudaInstallation->print(OS); RocmInstallation->print(OS); } + +void DarwinClang::printVerboseInfo(raw_ostream &OS) const { + // Print the information about how we detected the GCC installation. + GCCInstallation.print(OS); + Darwin::printVerboseInfo(OS); +} diff --git a/clang/lib/Driver/ToolChains/Darwin.h b/clang/lib/Driver/ToolChains/Darwin.h index 3cefe489f7cf4..06990df8f7bbe 100644 --- a/clang/lib/Driver/ToolChains/Darwin.h +++ b/clang/lib/Driver/ToolChains/Darwin.h @@ -9,6 +9,7 @@ #ifndef LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_DARWIN_H #define LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_DARWIN_H +#include "Gnu.h" #include "clang/Basic/DarwinSDKInfo.h" #include "clang/Basic/LangOptions.h" #include "clang/Driver/CudaInstallationDetector.h" @@ -643,6 +644,9 @@ class LLVM_LIBRARY_VISIBILITY Darwin : public AppleMachO { /// DarwinClang - The Darwin toolchain used by Clang. class LLVM_LIBRARY_VISIBILITY DarwinClang : public Darwin { +protected: + Generic_GCC::GCCInstallationDetector GCCInstallation; + public: DarwinClang(const Driver &D, const llvm::Triple &Triple, const llvm::opt::ArgList &Args); @@ -673,6 +677,8 @@ class LLVM_LIBRARY_VISIBILITY DarwinClang : public Darwin { void AddLinkARCArgs(const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs) const override; + void printVerboseInfo(raw_ostream &OS) const override; + unsigned GetDefaultDwarfVersion() const override; // Until dtrace (via CTF) and LLDB can deal with distributed debug info, // Darwin defaults to standalone/full debug info. @@ -689,6 +695,11 @@ class LLVM_LIBRARY_VISIBILITY DarwinClang : public Darwin { StringRef Sanitizer, bool shared = true) const; + bool + addLibStdCXXIncludePaths(Twine IncludeDir, StringRef Triple, + const llvm::opt::ArgList &DriverArgs, + llvm::opt::ArgStringList &CC1Args) const; + void AddGnuCPlusPlusIncludePaths(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args) const override; >From f180e434c2377b3c6857ad0297e313959be96afc Mon Sep 17 00:00:00 2001 From: Pierre Ossman <oss...@cendio.se> Date: Fri, 22 Aug 2025 13:29:40 +0200 Subject: [PATCH 7/7] Handle -static-libstdc++ for libstdc++ on Darwin --- clang/lib/Driver/ToolChains/Darwin.cpp | 27 +++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/clang/lib/Driver/ToolChains/Darwin.cpp b/clang/lib/Driver/ToolChains/Darwin.cpp index 6fde8cf931fa5..f71b875d08c11 100644 --- a/clang/lib/Driver/ToolChains/Darwin.cpp +++ b/clang/lib/Driver/ToolChains/Darwin.cpp @@ -1573,14 +1573,6 @@ void DarwinClang::AddLinkRuntimeLibArgs(const ArgList &Args, return; } - // Reject -static-libgcc for now, we can deal with this when and if someone - // cares. This is useful in situations where someone wants to statically link - // something like libstdc++, and needs its runtime support routines. - if (const Arg *A = Args.getLastArg(options::OPT_static_libgcc)) { - getDriver().Diag(diag::err_drv_unsupported_opt) << A->getAsString(Args); - return; - } - const SanitizerArgs &Sanitize = getSanitizerArgs(Args); if (!Sanitize.needsSharedRt()) { @@ -2929,7 +2921,24 @@ void AppleMachO::AddGnuCPlusPlusStdlibLibArgs( void DarwinClang::AddGnuCPlusPlusStdlibLibArgs( const ArgList &Args, ArgStringList &CmdArgs) const { - if (!GCCInstallation.isValid()) { + if (GCCInstallation.isValid()) { + if (Args.hasArg(options::OPT_static_libstdcxx)) { + // ld64 doesn't support -Bstatic, so we need to find the actual library + for (const auto &Path : getFilePaths()) { + llvm::SmallString<128> UsrLibStdCxx(Path); + llvm::sys::path::append(UsrLibStdCxx, "libstdc++.a"); + if (getVFS().exists(UsrLibStdCxx)) { + CmdArgs.push_back(Args.MakeArgString(UsrLibStdCxx)); + // libstdcxx++ needs symbols from here + if (Args.hasArg(options::OPT_static_libgcc)) + CmdArgs.push_back("-lgcc_eh"); + else + CmdArgs.push_back("-lgcc_s.1"); + return; + } + } + } + } else { // Unfortunately, -lstdc++ doesn't always exist in the standard search path; // it was previously found in the gcc lib dir. However, for all the Darwin // platforms we care about it was -lstdc++.6, so we search for that _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits