[lld] Add (ignored) /link flag to lld-link for compatibility with link.exe (PR #168364)

Frankie Robertson via llvm-commits llvm-commits at lists.llvm.org
Mon Nov 17 05:03:36 PST 2025


https://github.com/frankier created https://github.com/llvm/llvm-project/pull/168364

Various build tools may produce command lines invoking clang-cl and lld-link which contain /link twice like so: e.g. `clang-cl.exe sanitycheckcpp.cc /Fesanitycheckcpp.exe .... /link /link ...`

If link.exe is used, it ignores the extra `/link` and just issues a warning, however lld-link tries to treat `/link` as a file name.

This PR adds a flag which is ignored in order to improve compatibility with link.exe

There's some extra context including an "in-the-wild" example and reproducer of the problem here: https://github.com/frankier/meson_clang_win_activation

>From e659f04ccacb17d892da5811d5f058328c82e500 Mon Sep 17 00:00:00 2001
From: Frankie Robertson <frankie at robertson.name>
Date: Mon, 17 Nov 2025 14:52:23 +0200
Subject: [PATCH] Add ignored /link flag to lld-link

---
 lld/COFF/DriverUtils.cpp  | 3 +++
 lld/COFF/Options.td       | 1 +
 lld/test/COFF/driver.test | 3 +++
 3 files changed, 7 insertions(+)

diff --git a/lld/COFF/DriverUtils.cpp b/lld/COFF/DriverUtils.cpp
index 10a3934d53284..42c7f93381510 100644
--- a/lld/COFF/DriverUtils.cpp
+++ b/lld/COFF/DriverUtils.cpp
@@ -862,6 +862,9 @@ opt::InputArgList ArgParser::parse(ArrayRef<const char *> argv) {
                 << "', did you mean '" << nearest << "'";
   }
 
+  if (args.hasArg(OPT_link))
+    Warn(ctx) << "ignoring /link, did you pass it multiple times?";
+
   if (args.hasArg(OPT_lib))
     Warn(ctx) << "ignoring /lib since it's not the first argument";
 
diff --git a/lld/COFF/Options.td b/lld/COFF/Options.td
index d77478fc9c987..6c4c7f897513d 100644
--- a/lld/COFF/Options.td
+++ b/lld/COFF/Options.td
@@ -71,6 +71,7 @@ def noimplib : F<"noimplib">,
 def lib : F<"lib">,
     HelpText<"Act like lib.exe; must be first argument if present">;
 def libpath : P<"libpath", "Additional library search path">;
+def link : F<"link">, HelpText<"Ignored for compatibility">;
 def linkrepro : Joined<["/", "-", "/?", "-?"], "linkrepro:">,
     MetaVarName<"directory">,
     HelpText<"Write repro.tar containing inputs and command to reproduce link">;
diff --git a/lld/test/COFF/driver.test b/lld/test/COFF/driver.test
index 8f58ff44e83e3..1c265bff75df5 100644
--- a/lld/test/COFF/driver.test
+++ b/lld/test/COFF/driver.test
@@ -17,6 +17,9 @@ LIBHELP: OVERVIEW: LLVM Lib
 # RUN: env LLD_IN_TEST=1 not lld-link /WX /lib 2>&1 | FileCheck -check-prefix=LIBBAD %s
 LIBBAD: ignoring /lib since it's not the first argument
 
+# RUN: env LLD_IN_TEST=1 not lld-link /link 2>&1 | FileCheck -check-prefix=LINKBAD %s
+LINKBAD: ignoring /link, did you pass it multiple times?
+
 # RUN: yaml2obj %p/Inputs/hello32.yaml -o %t.obj
 # RUN: not lld-link /out:/ %t.obj 2>&1 | FileCheck -check-prefix=DIR %s
 DIR: cannot open output file



More information about the llvm-commits mailing list