From 40e018ad4a92a20442ad34b0a5b988394e15e609 Mon Sep 17 00:00:00 2001 From: Brian Cain Date: Thu, 21 Nov 2024 19:46:04 -0800 Subject: [PATCH] [clang] recognize any *-ld.lld variant If we create a cross toolchain with a ${triple}-ld.lld symlink, clang finds that symlink and when it uses it, it's not recognized as "lld". Let's resolve that symlink and consider it when determining lld-ness. For example, clang provides hexagon-link specific link arguments such as `-mcpu=hexagonv65` and `-march=hexagon` when hexagon-unknown-linux-musl-ld.lld is found. lld rejects this with the following error: hexagon-unknown-linux-musl-ld.lld: error: unknown emulation: cpu=hexagonv65 --- clang/lib/Driver/ToolChain.cpp | 12 +++++++++--- clang/lib/Driver/ToolChains/Hexagon.cpp | 8 +++++--- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/clang/lib/Driver/ToolChain.cpp b/clang/lib/Driver/ToolChain.cpp index 0d426a467e9a3..f912cd9229b81 100644 --- a/clang/lib/Driver/ToolChain.cpp +++ b/clang/lib/Driver/ToolChain.cpp @@ -964,7 +964,7 @@ std::string ToolChain::GetLinkerPath(bool *LinkerIsLLD) const { StringRef UseLinker = A ? A->getValue() : CLANG_DEFAULT_LINKER; // --ld-path= takes precedence over -fuse-ld= and specifies the executable - // name. -B, COMPILER_PATH and PATH and consulted if the value does not + // name. -B, COMPILER_PATH and PATH are consulted if the value does not // contain a path component separator. // -fuse-ld=lld can be used with --ld-path= to inform clang that the binary // that --ld-path= points to is lld. @@ -974,8 +974,11 @@ std::string ToolChain::GetLinkerPath(bool *LinkerIsLLD) const { if (llvm::sys::path::parent_path(Path).empty()) Path = GetProgramPath(A->getValue()); if (llvm::sys::fs::can_execute(Path)) { + SmallString<1024> RealPath; + if (llvm::sys::fs::real_path(Path, RealPath)) + RealPath = llvm::sys::path::stem(RealPath); if (LinkerIsLLD) - *LinkerIsLLD = UseLinker == "lld"; + *LinkerIsLLD = UseLinker == "lld" || RealPath == "lld"; return std::string(Path); } } @@ -1014,8 +1017,11 @@ std::string ToolChain::GetLinkerPath(bool *LinkerIsLLD) const { std::string LinkerPath(GetProgramPath(LinkerName.c_str())); if (llvm::sys::fs::can_execute(LinkerPath)) { + SmallString<1024> RealPath; + if (llvm::sys::fs::real_path(LinkerPath, RealPath)) + RealPath = llvm::sys::path::stem(RealPath); if (LinkerIsLLD) - *LinkerIsLLD = UseLinker == "lld"; + *LinkerIsLLD = UseLinker == "lld" || RealPath == "lld"; return LinkerPath; } } diff --git a/clang/lib/Driver/ToolChains/Hexagon.cpp b/clang/lib/Driver/ToolChains/Hexagon.cpp index 29781399cbab4..625979d56730b 100644 --- a/clang/lib/Driver/ToolChains/Hexagon.cpp +++ b/clang/lib/Driver/ToolChains/Hexagon.cpp @@ -294,9 +294,11 @@ constructHexagonLinkArgs(Compilation &C, const JobAction &JA, bool IncStartFiles = !Args.hasArg(options::OPT_nostartfiles); bool IncDefLibs = !Args.hasArg(options::OPT_nodefaultlibs); bool UseG0 = false; - const char *Exec = Args.MakeArgString(HTC.GetLinkerPath()); - bool UseLLD = (llvm::sys::path::filename(Exec).equals_insensitive("ld.lld") || - llvm::sys::path::stem(Exec).equals_insensitive("ld.lld")); + bool UseLLD = false; + const char *Exec = Args.MakeArgString(HTC.GetLinkerPath(&UseLLD)); + UseLLD = UseLLD || + llvm::sys::path::filename(Exec).equals_insensitive("ld.lld") || + llvm::sys::path::stem(Exec).equals_insensitive("ld.lld"); bool UseShared = IsShared && !IsStatic; StringRef CpuVer = toolchains::HexagonToolChain::GetTargetCPUVersion(Args);