[clang] [Cygwin] Cygwin driver (PR #74933)

via cfe-commits cfe-commits at lists.llvm.org
Sat Dec 9 05:53:14 PST 2023


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang-driver

@llvm/pr-subscribers-clang

Author: εΎζŒζ’ Xu Chiheng (xu-chiheng)

<details>
<summary>Changes</summary>



---

Patch is 35.89 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/74933.diff


5 Files Affected:

- (modified) clang/lib/Driver/CMakeLists.txt (+1) 
- (modified) clang/lib/Driver/Driver.cpp (+4) 
- (added) clang/lib/Driver/ToolChains/Cygwin.cpp (+731) 
- (added) clang/lib/Driver/ToolChains/Cygwin.h (+125) 
- (modified) clang/lib/Lex/InitHeaderSearch.cpp (+4-26) 


``````````diff
diff --git a/clang/lib/Driver/CMakeLists.txt b/clang/lib/Driver/CMakeLists.txt
index 58427e3f83c420..7ab5a1ee963515 100644
--- a/clang/lib/Driver/CMakeLists.txt
+++ b/clang/lib/Driver/CMakeLists.txt
@@ -51,6 +51,7 @@ add_clang_library(clangDriver
   ToolChains/CrossWindows.cpp
   ToolChains/CSKYToolChain.cpp
   ToolChains/Cuda.cpp
+  ToolChains/Cygwin.cpp
   ToolChains/Darwin.cpp
   ToolChains/DragonFly.cpp
   ToolChains/Flang.cpp
diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp
index e241706b9082ee..b6f3da3a006f4e 100644
--- a/clang/lib/Driver/Driver.cpp
+++ b/clang/lib/Driver/Driver.cpp
@@ -17,6 +17,7 @@
 #include "ToolChains/Clang.h"
 #include "ToolChains/CrossWindows.h"
 #include "ToolChains/Cuda.h"
+#include "ToolChains/Cygwin.h"
 #include "ToolChains/Darwin.h"
 #include "ToolChains/DragonFly.h"
 #include "ToolChains/FreeBSD.h"
@@ -6263,6 +6264,9 @@ const ToolChain &Driver::getToolChain(const ArgList &Args,
         else
           TC = std::make_unique<toolchains::Generic_GCC>(*this, Target, Args);
         break;
+      case llvm::Triple::Cygnus:
+        TC = std::make_unique<toolchains::Cygwin>(*this, Target, Args);
+        break;
       case llvm::Triple::GNU:
         TC = std::make_unique<toolchains::MinGW>(*this, Target, Args);
         break;
diff --git a/clang/lib/Driver/ToolChains/Cygwin.cpp b/clang/lib/Driver/ToolChains/Cygwin.cpp
new file mode 100644
index 00000000000000..8aa9cf5c8ec034
--- /dev/null
+++ b/clang/lib/Driver/ToolChains/Cygwin.cpp
@@ -0,0 +1,731 @@
+//===--- Cygwin.cpp - CygwinToolChain Implementation ------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "Cygwin.h"
+#include "CommonArgs.h"
+#include "clang/Config/config.h"
+#include "clang/Driver/Compilation.h"
+#include "clang/Driver/Driver.h"
+#include "clang/Driver/DriverDiagnostic.h"
+#include "clang/Driver/InputInfo.h"
+#include "clang/Driver/Options.h"
+#include "clang/Driver/SanitizerArgs.h"
+#include "llvm/Option/ArgList.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/Path.h"
+#include "llvm/Support/VirtualFileSystem.h"
+#include <system_error>
+
+using namespace clang::diag;
+using namespace clang::driver;
+using namespace clang;
+using namespace llvm::opt;
+
+/// Cygwin Tools
+void tools::Cygwin::Assembler::ConstructJob(Compilation &C, const JobAction &JA,
+                                           const InputInfo &Output,
+                                           const InputInfoList &Inputs,
+                                           const ArgList &Args,
+                                           const char *LinkingOutput) const {
+  claimNoWarnArgs(Args);
+  ArgStringList CmdArgs;
+
+  if (getToolChain().getArch() == llvm::Triple::x86) {
+    CmdArgs.push_back("--32");
+  } else if (getToolChain().getArch() == llvm::Triple::x86_64) {
+    CmdArgs.push_back("--64");
+  }
+
+  Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, options::OPT_Xassembler);
+
+  CmdArgs.push_back("-o");
+  CmdArgs.push_back(Output.getFilename());
+
+  for (const auto &II : Inputs)
+    CmdArgs.push_back(II.getFilename());
+
+  const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("as"));
+  C.addCommand(std::make_unique<Command>(JA, *this, ResponseFileSupport::None(),
+                                         Exec, CmdArgs, Inputs, Output));
+
+  if (Args.hasArg(options::OPT_gsplit_dwarf))
+    SplitDebugInfo(getToolChain(), C, *this, JA, Args, Output,
+                   SplitDebugName(JA, Args, Inputs[0], Output));
+}
+
+void tools::Cygwin::Linker::AddLibGCC(const ArgList &Args,
+                                     ArgStringList &CmdArgs) const {
+  // Make use of compiler-rt if --rtlib option is used
+  ToolChain::RuntimeLibType RLT = getToolChain().GetRuntimeLibType(Args);
+  if (RLT == ToolChain::RLT_Libgcc) {
+    bool Static = Args.hasArg(options::OPT_static_libgcc) ||
+                  Args.hasArg(options::OPT_static);
+    bool Shared = Args.hasArg(options::OPT_shared);
+    bool CXX = getToolChain().getDriver().CCCIsCXX();
+
+    if (Static || (!CXX && !Shared)) {
+      CmdArgs.push_back("-lgcc");
+      CmdArgs.push_back("-lgcc_eh");
+    } else {
+      CmdArgs.push_back("-lgcc_s");
+      CmdArgs.push_back("-lgcc");
+    }
+  } else {
+    AddRunTimeLibs(getToolChain(), getToolChain().getDriver(), CmdArgs, Args);
+  }
+
+  CmdArgs.push_back("-lcygwin");
+}
+
+void tools::Cygwin::Linker::ConstructJob(Compilation &C, const JobAction &JA,
+                                        const InputInfo &Output,
+                                        const InputInfoList &Inputs,
+                                        const ArgList &Args,
+                                        const char *LinkingOutput) const {
+  const ToolChain &TC = getToolChain();
+  const Driver &D = TC.getDriver();
+  const SanitizerArgs &Sanitize = TC.getSanitizerArgs(Args);
+
+  ArgStringList CmdArgs;
+
+  // Silence warning for "clang -g foo.o -o foo"
+  Args.ClaimAllArgs(options::OPT_g_Group);
+  // and "clang -emit-llvm foo.o -o foo"
+  Args.ClaimAllArgs(options::OPT_emit_llvm);
+  // and for "clang -w foo.o -o foo". Other warning options are already
+  // handled somewhere else.
+  Args.ClaimAllArgs(options::OPT_w);
+
+  if (!D.SysRoot.empty())
+    CmdArgs.push_back(Args.MakeArgString("--sysroot=" + D.SysRoot));
+
+  if (Args.hasArg(options::OPT_s))
+    CmdArgs.push_back("-s");
+
+  CmdArgs.push_back("-m");
+  switch (TC.getArch()) {
+  case llvm::Triple::x86:
+    CmdArgs.push_back("i386pe");
+    break;
+  case llvm::Triple::x86_64:
+    CmdArgs.push_back("i386pep");
+    break;
+  case llvm::Triple::arm:
+  case llvm::Triple::thumb:
+    // FIXME: this is incorrect for WinCE
+    CmdArgs.push_back("thumb2pe");
+    break;
+  case llvm::Triple::aarch64:
+    CmdArgs.push_back("arm64pe");
+    break;
+  default:
+    D.Diag(diag::err_target_unknown_triple) << TC.getEffectiveTriple().str();
+  }
+
+  if (!Args.getLastArgValue(options::OPT_fuse_ld_EQ, "link").equals_insensitive("lld")) {
+    if (TC.getArch() == llvm::Triple::x86) {
+      CmdArgs.push_back("--wrap");
+      CmdArgs.push_back("_Znwj");
+      CmdArgs.push_back("--wrap");
+      CmdArgs.push_back("_Znaj");
+      CmdArgs.push_back("--wrap");
+      CmdArgs.push_back("_ZnwjRKSt9nothrow_t");
+      CmdArgs.push_back("--wrap");
+      CmdArgs.push_back("_ZnajRKSt9nothrow_t");
+    } else {
+      CmdArgs.push_back("--wrap");
+      CmdArgs.push_back("_Znwm");
+      CmdArgs.push_back("--wrap");
+      CmdArgs.push_back("_Znam");
+      CmdArgs.push_back("--wrap");
+      CmdArgs.push_back("_ZnwmRKSt9nothrow_t");
+      CmdArgs.push_back("--wrap");
+      CmdArgs.push_back("_ZnamRKSt9nothrow_t");
+    }
+    CmdArgs.push_back("--wrap");
+    CmdArgs.push_back("_ZdlPv");
+    CmdArgs.push_back("--wrap");
+    CmdArgs.push_back("_ZdaPv");
+    CmdArgs.push_back("--wrap");
+    CmdArgs.push_back("_ZdlPvRKSt9nothrow_t");
+    CmdArgs.push_back("--wrap");
+    CmdArgs.push_back("_ZdaPvRKSt9nothrow_t");
+  }
+
+  Arg *SubsysArg =
+      Args.getLastArg(options::OPT_mwindows, options::OPT_mconsole);
+  if (SubsysArg && SubsysArg->getOption().matches(options::OPT_mwindows)) {
+    CmdArgs.push_back("--subsystem");
+    CmdArgs.push_back("windows");
+  } else if (SubsysArg &&
+             SubsysArg->getOption().matches(options::OPT_mconsole)) {
+    CmdArgs.push_back("--subsystem");
+    CmdArgs.push_back("console");
+  }
+
+  if (Args.hasArg(options::OPT_mdll))
+    CmdArgs.push_back("--dll");
+  else if (Args.hasArg(options::OPT_shared))
+    CmdArgs.push_back("--shared");
+  if (Args.hasArg(options::OPT_static))
+    CmdArgs.push_back("-Bstatic");
+  else
+    CmdArgs.push_back("-Bdynamic");
+  if (Args.hasArg(options::OPT_mdll) || Args.hasArg(options::OPT_shared)) {
+    CmdArgs.push_back("-e");
+    if (TC.getArch() == llvm::Triple::x86)
+      CmdArgs.push_back("__cygwin_dll_entry at 12");
+    else
+      CmdArgs.push_back("_cygwin_dll_entry");
+    CmdArgs.push_back("--enable-auto-image-base");
+  }
+  CmdArgs.push_back("--dynamicbase");
+
+  if (Args.hasArg(options::OPT_Z_Xlinker__no_demangle))
+    CmdArgs.push_back("--no-demangle");
+
+  if (Arg *A = Args.getLastArg(options::OPT_mguard_EQ)) {
+    StringRef GuardArgs = A->getValue();
+    if (GuardArgs == "none")
+      CmdArgs.push_back("--no-guard-cf");
+    else if (GuardArgs == "cf" || GuardArgs == "cf-nochecks")
+      CmdArgs.push_back("--guard-cf");
+    else
+      D.Diag(diag::err_drv_unsupported_option_argument)
+          << A->getSpelling() << GuardArgs;
+  }
+
+  CmdArgs.push_back("-o");
+  const char *OutputFile = Output.getFilename();
+  // GCC implicitly adds an .exe extension if it is given an output file name
+  // that lacks an extension.
+  // GCC used to do this only when the compiler itself runs on windows, but
+  // since GCC 8 it does the same when cross compiling as well.
+  if (!llvm::sys::path::has_extension(OutputFile)) {
+    CmdArgs.push_back(Args.MakeArgString(Twine(OutputFile) + ".exe"));
+    OutputFile = CmdArgs.back();
+  } else
+    CmdArgs.push_back(OutputFile);
+
+  // FIXME: add -N, -n flags
+  Args.AddLastArg(CmdArgs, options::OPT_r);
+  Args.AddLastArg(CmdArgs, options::OPT_s);
+  Args.AddLastArg(CmdArgs, options::OPT_t);
+  Args.AddAllArgs(CmdArgs, options::OPT_u_Group);
+  Args.AddLastArg(CmdArgs, options::OPT_Z_Flag);
+
+  // Add asan_dynamic as the first import lib before other libs. This allows
+  // asan to be initialized as early as possible to increase its instrumentation
+  // coverage to include other user DLLs which has not been built with asan.
+  if (Sanitize.needsAsanRt() && !Args.hasArg(options::OPT_nostdlib) &&
+      !Args.hasArg(options::OPT_nodefaultlibs)) {
+    // Cygwin always links against a shared Cygwin DLL.
+    CmdArgs.push_back(
+        TC.getCompilerRTArgString(Args, "asan_dynamic", ToolChain::FT_Shared));
+  }
+
+  if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) {
+    if (Args.hasArg(options::OPT_shared) || Args.hasArg(options::OPT_mdll)) {
+      CmdArgs.push_back(Args.MakeArgString(TC.GetFilePath("crtbeginS.o")));
+    } else {
+      CmdArgs.push_back(Args.MakeArgString(TC.GetFilePath("crt0.o")));
+      CmdArgs.push_back(Args.MakeArgString(TC.GetFilePath("crtbegin.o")));
+    }
+    if (Args.hasArg(options::OPT_pg))
+      CmdArgs.push_back(Args.MakeArgString(TC.GetFilePath("gcrt0.o")));
+  }
+
+  Args.AddAllArgs(CmdArgs, options::OPT_L);
+  TC.AddFilePathLibArgs(Args, CmdArgs);
+
+  // Add the compiler-rt library directories if they exist to help
+  // the linker find the various sanitizer, builtin, and profiling runtimes.
+  for (const auto &LibPath : TC.getLibraryPaths()) {
+    if (TC.getVFS().exists(LibPath))
+      CmdArgs.push_back(Args.MakeArgString("-L" + LibPath));
+  }
+  auto CRTPath = TC.getCompilerRTPath();
+  if (TC.getVFS().exists(CRTPath))
+    CmdArgs.push_back(Args.MakeArgString("-L" + CRTPath));
+
+  AddLinkerInputs(TC, Inputs, Args, CmdArgs, JA);
+
+  if (C.getDriver().IsFlangMode()) {
+    addFortranRuntimeLibraryPath(TC, Args, CmdArgs);
+    addFortranRuntimeLibs(TC, CmdArgs);
+  }
+
+  // TODO: Add profile stuff here
+
+  if (TC.ShouldLinkCXXStdlib(Args)) {
+    bool OnlyLibstdcxxStatic = Args.hasArg(options::OPT_static_libstdcxx) &&
+                               !Args.hasArg(options::OPT_static);
+    if (OnlyLibstdcxxStatic)
+      CmdArgs.push_back("-Bstatic");
+    TC.AddCXXStdlibLibArgs(Args, CmdArgs);
+    if (OnlyLibstdcxxStatic)
+      CmdArgs.push_back("-Bdynamic");
+  }
+
+  bool HasWindowsApp = false;
+  for (auto Lib : Args.getAllArgValues(options::OPT_l)) {
+    if (Lib == "windowsapp") {
+      HasWindowsApp = true;
+      break;
+    }
+  }
+
+  if (!Args.hasArg(options::OPT_nostdlib)) {
+    if (!Args.hasArg(options::OPT_nodefaultlibs)) {
+      if (Args.hasArg(options::OPT_static))
+        CmdArgs.push_back("--start-group");
+
+      if (Args.hasArg(options::OPT_fstack_protector) ||
+          Args.hasArg(options::OPT_fstack_protector_strong) ||
+          Args.hasArg(options::OPT_fstack_protector_all)) {
+        CmdArgs.push_back("-lssp_nonshared");
+        CmdArgs.push_back("-lssp");
+      }
+
+      if (Args.hasFlag(options::OPT_fopenmp, options::OPT_fopenmp_EQ,
+                       options::OPT_fno_openmp, false)) {
+        switch (TC.getDriver().getOpenMPRuntime(Args)) {
+        case Driver::OMPRT_OMP:
+          CmdArgs.push_back("-lomp");
+          break;
+        case Driver::OMPRT_IOMP5:
+          CmdArgs.push_back("-liomp5md");
+          break;
+        case Driver::OMPRT_GOMP:
+          CmdArgs.push_back("-lgomp");
+          break;
+        case Driver::OMPRT_Unknown:
+          // Already diagnosed.
+          break;
+        }
+      }
+
+      AddLibGCC(Args, CmdArgs);
+
+      if (Sanitize.needsAsanRt()) {
+        // Cygwin always links against a shared Cygwin DLL.
+        CmdArgs.push_back(TC.getCompilerRTArgString(Args, "asan_dynamic",
+                                                    ToolChain::FT_Shared));
+        CmdArgs.push_back(
+            TC.getCompilerRTArgString(Args, "asan_dynamic_runtime_thunk"));
+        CmdArgs.push_back("--require-defined");
+        CmdArgs.push_back(TC.getArch() == llvm::Triple::x86
+                              ? "___asan_seh_interceptor"
+                              : "__asan_seh_interceptor");
+        // Make sure the linker consider all object files from the dynamic
+        // runtime thunk.
+        CmdArgs.push_back("--whole-archive");
+        CmdArgs.push_back(
+            TC.getCompilerRTArgString(Args, "asan_dynamic_runtime_thunk"));
+        CmdArgs.push_back("--no-whole-archive");
+      }
+
+      TC.addProfileRTLibs(Args, CmdArgs);
+
+      if (!HasWindowsApp) {
+        // Add system libraries. If linking to libwindowsapp.a, that import
+        // library replaces all these and we shouldn't accidentally try to
+        // link to the normal desktop mode dlls.
+        if (Args.hasArg(options::OPT_mwindows)) {
+          CmdArgs.push_back("-lgdi32");
+          CmdArgs.push_back("-lcomdlg32");
+        }
+        CmdArgs.push_back("-ladvapi32");
+        CmdArgs.push_back("-lshell32");
+        CmdArgs.push_back("-luser32");
+        CmdArgs.push_back("-lkernel32");
+      }
+
+      if (Args.hasArg(options::OPT_static)) {
+        CmdArgs.push_back("--end-group");
+      } else {
+        AddLibGCC(Args, CmdArgs);
+        if (!HasWindowsApp)
+          CmdArgs.push_back("-lkernel32");
+      }
+    }
+
+    if (!Args.hasArg(options::OPT_nostartfiles)) {
+      // Add crtfastmath.o if available and fast math is enabled.
+      TC.addFastMathRuntimeIfAvailable(Args, CmdArgs);
+
+      CmdArgs.push_back(Args.MakeArgString(TC.GetFilePath("crtend.o")));
+    }
+  }
+  const char *Exec = Args.MakeArgString(TC.GetLinkerPath());
+  C.addCommand(std::make_unique<Command>(JA, *this,
+                                         ResponseFileSupport::AtFileUTF8(),
+                                         Exec, CmdArgs, Inputs, Output));
+}
+
+static bool isCrossCompiling(const llvm::Triple &T, bool RequireArchMatch) {
+  llvm::Triple HostTriple(llvm::Triple::normalize(LLVM_HOST_TRIPLE));
+  if (!HostTriple.isWindowsCygwinEnvironment())
+    return true;
+  if (RequireArchMatch && HostTriple.getArch() != T.getArch())
+    return true;
+  return false;
+}
+
+// Simplified from Generic_GCC::GCCInstallationDetector::ScanLibDirForGCCTriple.
+static bool findGccVersion(StringRef LibDir, std::string &GccLibDir,
+                           std::string &Ver,
+                           toolchains::Generic_GCC::GCCVersion &Version) {
+  Version = toolchains::Generic_GCC::GCCVersion::Parse("0.0.0");
+  std::error_code EC;
+  for (llvm::sys::fs::directory_iterator LI(LibDir, EC), LE; !EC && LI != LE;
+       LI = LI.increment(EC)) {
+    StringRef VersionText = llvm::sys::path::filename(LI->path());
+    auto CandidateVersion =
+        toolchains::Generic_GCC::GCCVersion::Parse(VersionText);
+    if (CandidateVersion.Major == -1)
+      continue;
+    if (CandidateVersion <= Version)
+      continue;
+    Version = CandidateVersion;
+    Ver = std::string(VersionText);
+    GccLibDir = LI->path();
+  }
+  return Ver.size();
+}
+
+static llvm::Triple getLiteralTriple(const Driver &D, const llvm::Triple &T) {
+  llvm::Triple LiteralTriple(D.getTargetTriple());
+  // The arch portion of the triple may be overridden by -m32/-m64.
+  LiteralTriple.setArchName(T.getArchName());
+  return LiteralTriple;
+}
+
+void toolchains::Cygwin::findGccLibDir(const llvm::Triple &LiteralTriple) {
+  llvm::SmallVector<llvm::SmallString<32>, 5> SubdirNames;
+  SubdirNames.emplace_back(getTriple().getArchName());
+  SubdirNames[0] += "-pc-cygwin";
+  SubdirNames.emplace_back("cygwin");
+  if (SubdirName.empty())
+    SubdirName = SubdirNames[0].str();
+  // lib: Arch Linux, Ubuntu, Windows
+  // lib64: openSUSE Linux
+  for (StringRef CandidateLib : {"lib", "lib64"}) {
+    for (StringRef CandidateSysroot : SubdirNames) {
+      llvm::SmallString<1024> LibDir(Base);
+      llvm::sys::path::append(LibDir, CandidateLib, "gcc", CandidateSysroot);
+      if (findGccVersion(LibDir, GccLibDir, Ver, GccVer)) {
+        SubdirName = std::string(CandidateSysroot);
+        return;
+      }
+    }
+  }
+}
+
+static llvm::ErrorOr<std::string> findGcc(const llvm::Triple &LiteralTriple,
+                                          const llvm::Triple &T) {
+  llvm::SmallVector<llvm::SmallString<32>, 5> Gccs;
+  Gccs.emplace_back(T.getArchName());
+  Gccs[0] += "-pc-cygwin-gcc";
+  Gccs.emplace_back("cygwin-gcc");
+  // Please do not add "gcc" here
+  for (StringRef CandidateGcc : Gccs)
+    if (llvm::ErrorOr<std::string> GPPName = llvm::sys::findProgramByName(CandidateGcc))
+      return GPPName;
+  return make_error_code(std::errc::no_such_file_or_directory);
+}
+
+static llvm::ErrorOr<std::string>
+findClangRelativeSysroot(const Driver &D, const llvm::Triple &LiteralTriple,
+                         const llvm::Triple &T, std::string &SubdirName) {
+  llvm::SmallVector<llvm::SmallString<32>, 4> Subdirs;
+  Subdirs.emplace_back(T.str());
+  Subdirs.emplace_back(T.getArchName());
+  Subdirs[1] += "-pc-cygwin";
+  StringRef ClangRoot = llvm::sys::path::parent_path(D.getInstalledDir());
+  StringRef Sep = llvm::sys::path::get_separator();
+  for (StringRef CandidateSubdir : Subdirs) {
+    if (llvm::sys::fs::is_directory(ClangRoot + Sep + CandidateSubdir)) {
+      SubdirName = std::string(CandidateSubdir);
+      return (ClangRoot + Sep + CandidateSubdir).str();
+    }
+  }
+  return make_error_code(std::errc::no_such_file_or_directory);
+}
+
+toolchains::Cygwin::Cygwin(const Driver &D, const llvm::Triple &Triple,
+                         const ArgList &Args)
+    : ToolChain(D, Triple, Args), CudaInstallation(D, Triple, Args),
+      RocmInstallation(D, Triple, Args) {
+  getProgramPaths().push_back(getDriver().getInstalledDir());
+
+  // The sequence for detecting a sysroot here should be kept in sync with
+  // the testTriple function below.
+  llvm::Triple LiteralTriple = getLiteralTriple(D, getTriple());
+  if (getDriver().SysRoot.size())
+    Base = getDriver().SysRoot;
+  // Look for <clang-bin>/../<triplet>; if found, use <clang-bin>/.. as the
+  // base as it could still be a base for a gcc setup with libgcc.
+  else if (llvm::ErrorOr<std::string> TargetSubdir = findClangRelativeSysroot(
+               getDriver(), LiteralTriple, getTriple(), SubdirName))
+    Base = std::string(llvm::sys::path::parent_path(TargetSubdir.get()));
+  else if (llvm::ErrorOr<std::string> GPPName =
+               findGcc(LiteralTriple, getTriple()))
+    Base = std::string(llvm::sys::path::parent_path(
+        llvm::sys::path::parent_path(GPPName.get())));
+  else
+    Base = std::string(
+        llvm::sys::path::parent_path(getDriver().getInstalledDir()));
+
+  Base += llvm::sys::path::get_separator();
+  findGccLibDir(LiteralTriple);
+  TripleDirName = SubdirName;
+  // GccLibDir must precede Base/lib so that the
+  // correct crtbegin.o ,cetend.o would be found.
+  getFilePaths().push_back(GccLibDir);
+  getFilePath...
[truncated]

``````````

</details>


https://github.com/llvm/llvm-project/pull/74933


More information about the cfe-commits mailing list