Author: Aiden Grossman
Date: 2026-03-05T06:46:57-08:00
New Revision: 8ef122433149b10be71f01b9c5fafc8e269b1a63

URL: 
https://github.com/llvm/llvm-project/commit/8ef122433149b10be71f01b9c5fafc8e269b1a63
DIFF: 
https://github.com/llvm/llvm-project/commit/8ef122433149b10be71f01b9c5fafc8e269b1a63.diff

LOG: [LinkerWrapper] Add support for --no-canonical-prefixes

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.

Reviewers: jhuber6, Artem-B, sarnex

Pull Request: https://github.com/llvm/llvm-project/pull/184160

Added: 
    clang/test/Driver/linker-wrapper-canonical-prefixes.c

Modified: 
    clang/lib/Driver/ToolChains/Clang.cpp
    clang/test/Driver/hip-options.hip
    clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp
    clang/tools/clang-linker-wrapper/LinkerWrapperOpts.td

Removed: 
    


################################################################################
diff  --git a/clang/lib/Driver/ToolChains/Clang.cpp 
b/clang/lib/Driver/ToolChains/Clang.cpp
index e860136aae5b3..36ba3d35ed012 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -9335,6 +9335,7 @@ void LinkerWrapper::ConstructJob(Compilation &C, const 
JobAction &JA,
       OPT_save_temps_EQ,
       OPT_mcode_object_version_EQ,
       OPT_load,
+      OPT_no_canonical_prefixes,
       OPT_fno_lto,
       OPT_flto,
       OPT_flto_partitions_EQ,
@@ -9562,6 +9563,10 @@ void LinkerWrapper::ConstructJob(Compilation &C, const 
JobAction &JA,
     }
   }
 
+  // Propagate -no-canonical-prefixes.
+  if (Args.hasArg(options::OPT_no_canonical_prefixes))
+    CmdArgs.push_back("--no-canonical-prefixes");
+
   const char *Exec =
       
Args.MakeArgString(getToolChain().GetProgramPath("clang-linker-wrapper"));
 

diff  --git a/clang/test/Driver/hip-options.hip 
b/clang/test/Driver/hip-options.hip
index a6a66034f13de..ed20239605c22 100644
--- a/clang/test/Driver/hip-options.hip
+++ b/clang/test/Driver/hip-options.hip
@@ -88,6 +88,16 @@
 // HIPTHINLTO-NOT: "-cc1"{{.*}} "-triple" "x86_64-unknown-linux-gnu" {{.*}} 
"-flto-unit"
 // HIPTHINLTO: clang-linker-wrapper{{.*}} 
"--device-compiler=amdgcn-amd-amdhsa=-flto=thin"
 
+// Check -no-canonical-prefixes is propagated correctly.
+
+// RUN: %clang -### --target=x86_64-unknown-linux-gnu -nogpuinc -nogpulib \
+// RUN:   --cuda-gpu-arch=gfx906 -foffload-lto=thin -fwhole-program-vtables 
-no-canonical-prefixes %s 2>&1 \
+// RUN:   | FileCheck -check-prefix=HIPTHINLTO-NO-CANON-PREFIXES %s
+
+// Ensure that we invoke clang-linker-wrapper with --no-canonical-prefixes and
+// pass -no-canonical-prefixes as a device compiler flag.
+// HIPTHINLTO-NO-CANON-PREFIXES: clang-linker-wrapper{{.*}} 
"--device-compiler=amdgcn-amd-amdhsa=-no-canonical-prefixes" {{.*}} 
"--no-canonical-prefixes"
+
 // Check that -flto=thin is handled correctly, particularly with 
-fwhole-program-vtables.
 //
 // RUN: %clang -### --target=x86_64-unknown-linux-gnu -nogpuinc -nogpulib \

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..b71d75e7f9925
--- /dev/null
+++ b/clang/test/Driver/linker-wrapper-canonical-prefixes.c
@@ -0,0 +1,24 @@
+// 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: %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"

diff  --git a/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp 
b/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp
index 79b565b8d4dc8..54fad8a6ed5e7 100644
--- a/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp
+++ b/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp
@@ -134,6 +134,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 {
@@ -210,6 +213,8 @@ void printCommands(ArrayRef<StringRef> CmdArgs) {
 }
 
 std::string getExecutableDir(const char *Name) {
+  if (!CanonicalPrefixes)
+    return sys::path::parent_path(LinkerExecutable).str();
   void *Ptr = reinterpret_cast<void *>(&getExecutableDir);
   return sys::path::parent_path(sys::fs::getMainExecutable(Name, Ptr)).str();
 }
@@ -1351,6 +1356,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