https://github.com/boomanaiden154 created 
https://github.com/llvm/llvm-project/pull/184160

This is necessary to support build environments where the
compiler/associated tools are actually just symlinks into a CAS. Without
this, we try and resolve binaries relative to the real path of
clang-linker-wrapper, which is usually in a directory prefixed with the
first couple characters of a SHA digest and named with a SHA digest. We
also need to ensure that we propagate --no-canonical-prefixes to sub
clang invocations so that clang is able to resolve lld in such
environments.


>From 97c771d81570661cce67b57db5aaeebd7ff50437 Mon Sep 17 00:00:00 2001
From: Aiden Grossman <[email protected]>
Date: Mon, 2 Mar 2026 15:52:01 +0000
Subject: [PATCH] =?UTF-8?q?[=F0=9D=98=80=F0=9D=97=BD=F0=9D=97=BF]=20initia?=
 =?UTF-8?q?l=20version?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Created using spr 1.3.7
---
 .../linker-wrapper-canonical-prefixes.c       | 25 +++++++++++++++++++
 .../ClangLinkerWrapper.cpp                    |  9 +++++++
 .../clang-linker-wrapper/LinkerWrapperOpts.td |  4 +++
 3 files changed, 38 insertions(+)
 create mode 100644 clang/test/Driver/linker-wrapper-canonical-prefixes.c

diff --git a/clang/test/Driver/linker-wrapper-canonical-prefixes.c 
b/clang/test/Driver/linker-wrapper-canonical-prefixes.c
new file mode 100644
index 0000000000000..79152cc69c078
--- /dev/null
+++ b/clang/test/Driver/linker-wrapper-canonical-prefixes.c
@@ -0,0 +1,25 @@
+// UNSUPPORTED: system-windows
+// REQUIRES: x86-registered-target
+// REQUIRES: amdgpu-registered-target
+
+// An externally visible variable so static libraries extract.
+__attribute__((visibility("protected"), used)) int x;
+
+// RUN: rm -rf %t.test_dir && mkdir -p %t.test_dir
+// RUN: touch %t.test_dir/clang
+// RUN: chmod +x %t.test_dir/clang
+// RUN: ln -s clang-linker-wrapper %t.test_dir/clang-linker-wrapper
+
+// RUN: %clang -cc1 %s -triple x86_64-unknown-linux-gnu -emit-obj -o %t.elf.o
+// RUN: %clang -cc1 %s -triple amdgcn-amd-amdhsa -emit-llvm-bc -o %t.amdgpu.bc
+
+// RUN: llvm-offload-binary -o %t.out \
+// RUN:   
--image=file=%t.elf.o,kind=openmp,triple=amdgcn-amd-amdhsa,arch=gfx908 \
+// RUN:   
--image=file=%t.elf.o,kind=openmp,triple=amdgcn-amd-amdhsa,arch=gfx908
+// RUN: %clang -cc1 %s -triple x86_64-unknown-linux-gnu -emit-obj -o %t.o 
-fembed-offload-object=%t.out
+// RUN: %t.test_dir/clang-linker-wrapper 
--host-triple=x86_64-unknown-linux-gnu --dry-run \
+// RUN:   --linker-path=/usr/bin/ld %t.o -o a.out --no-canonical-prefixes 2>&1 
| FileCheck %s
+
+// Check that we resolve clang to the symlink rather than the bin/ directory
+// and that the sub-clang invocation was passed -no-canonical-prefixes.
+// CHECK: test_dir/clang" {{.*}} -no-canonical-prefixes
diff --git a/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp 
b/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp
index c49ce44432e5a..b2b6910cd7e0b 100644
--- a/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp
+++ b/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp
@@ -140,6 +140,9 @@ static std::list<SmallString<128>> TempFiles;
 /// Codegen flags for LTO backend.
 static codegen::RegisterCodeGenFlags CodeGenFlags;
 
+/// Whether or not to look through symlinks when resolving binaries.
+static bool CanonicalPrefixes = true;
+
 using OffloadingImage = OffloadBinary::OffloadingImage;
 
 namespace llvm {
@@ -219,6 +222,8 @@ void printCommands(ArrayRef<StringRef> CmdArgs) {
 }
 
 std::string getMainExecutable(const char *Name) {
+  if (!CanonicalPrefixes)
+    return sys::path::parent_path(LinkerExecutable).str();
   void *Ptr = (void *)(intptr_t)&getMainExecutable;
   auto COWPath = sys::fs::getMainExecutable(Name, Ptr);
   return sys::path::parent_path(COWPath).str();
@@ -539,6 +544,9 @@ Expected<StringRef> clang(ArrayRef<StringRef> InputFiles, 
const ArgList &Args,
       Args.MakeArgString("--target=" + Triple.getTriple()),
   };
 
+  if (!CanonicalPrefixes)
+    CmdArgs.push_back("-no-canonical-prefixes");
+
   if (!Arch.empty())
     Triple.isAMDGPU() ? CmdArgs.push_back(Args.MakeArgString("-mcpu=" + Arch))
                       : CmdArgs.push_back(Args.MakeArgString("-march=" + 
Arch));
@@ -1350,6 +1358,7 @@ int main(int Argc, char **Argv) {
   DryRun = Args.hasArg(OPT_dry_run);
   SaveTemps = Args.hasArg(OPT_save_temps);
   CudaBinaryPath = Args.getLastArgValue(OPT_cuda_path_EQ).str();
+  CanonicalPrefixes = !Args.hasArg(OPT_no_canonical_prefixes);
 
   llvm::Triple Triple(
       Args.getLastArgValue(OPT_host_triple_EQ, sys::getDefaultTargetTriple()));
diff --git a/clang/tools/clang-linker-wrapper/LinkerWrapperOpts.td 
b/clang/tools/clang-linker-wrapper/LinkerWrapperOpts.td
index ef3a16b2f58bb..973e5bb51a507 100644
--- a/clang/tools/clang-linker-wrapper/LinkerWrapperOpts.td
+++ b/clang/tools/clang-linker-wrapper/LinkerWrapperOpts.td
@@ -69,6 +69,10 @@ def emit_fatbin_only
       Flags<[WrapperOnlyOption]>,
       HelpText<"Emit fat binary directly without wrapping or host linking">;
 
+def no_canonical_prefixes : Flag<["--"], "no-canonical-prefixes">,
+  Flags<[WrapperOnlyOption]>,
+  HelpText<"Do not resolve symbolic links, turn relative paths into absolute 
ones, or do anything else to identify the executable">;
+
 // Flags passed to the device linker.
 def arch_EQ : Joined<["--"], "arch=">,
   Flags<[DeviceOnlyOption, HelpHidden]>, MetaVarName<"<arch>">,

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to