https://github.com/ian-twilightcoder created 
https://github.com/llvm/llvm-project/pull/224428

SwiftBuild passes -l to libtool, but I didn't catch it the first time around 
because it's not in the xcspec. It is in the unit test though. Go through all 
of the linker arguments and inputs and add the missing ones supported by 
libtool.

rdar://187418335

>From dd666670c578dcc2d92925a1c9794aa367dde632 Mon Sep 17 00:00:00 2001
From: Ian Anderson <[email protected]>
Date: Thu, 17 Sep 2026 13:54:13 -0700
Subject: [PATCH] [clang][driver][darwin] Add more libtool arguments used by
 SwiftBuild

SwiftBuild passes -l to libtool, but I didn't catch it the first time around 
because it's not in the xcspec. It is in the unit test though. Go through all 
of the linker arguments and inputs and add the missing ones supported by 
libtool.

rdar://187418335
---
 clang/lib/Driver/ToolChains/Darwin.cpp        | 28 +++++++++++++-
 .../test/Driver/darwin-static-lib-universal.c | 15 ++++++++
 clang/test/Driver/darwin-static-lib.c         | 37 +++++++++++++------
 3 files changed, 68 insertions(+), 12 deletions(-)
 create mode 100644 clang/test/Driver/darwin-static-lib-universal.c

diff --git a/clang/lib/Driver/ToolChains/Darwin.cpp 
b/clang/lib/Driver/ToolChains/Darwin.cpp
index 4100de3ad8fdc..0fb94d8712e69 100644
--- a/clang/lib/Driver/ToolChains/Darwin.cpp
+++ b/clang/lib/Driver/ToolChains/Darwin.cpp
@@ -927,6 +927,11 @@ void darwin::StaticLibTool::ConstructJob(Compilation &C, 
const JobAction &JA,
 
   AddMachOSysLibRoot(C, Args, CmdArgs);
   Args.AddAllArgs(CmdArgs, options::OPT_L);
+  Args.AddAllArgs(CmdArgs, options::OPT_F);
+
+  // -iframework should be forwarded as -F.
+  for (const Arg *A : Args.filtered(options::OPT_iframework))
+    CmdArgs.push_back(Args.MakeArgString(std::string("-F") + A->getValue()));
 
   if (!Args.hasFlag(options::OPT_static_lib_warn_no_symbols,
                     options::OPT_no_static_lib_warn_no_symbols,
@@ -938,11 +943,32 @@ void darwin::StaticLibTool::ConstructJob(Compilation &C, 
const JobAction &JA,
   CmdArgs.push_back("-o");
   CmdArgs.push_back(Output.getFilename());
 
-  Args.AddLastArg(CmdArgs, options::OPT_filelist);
+  // Add extra linker input arguments which are not treated as inputs
+  // (constructed via -Xarch_).
+  Args.AddAllArgValues(CmdArgs, options::OPT_Zlinker_input);
+
   for (const auto &II : Inputs) {
+    // Add filenames immediately.
     if (II.isFilename()) {
       CmdArgs.push_back(II.getFilename());
+      continue;
     }
+
+    // In some error cases, the input could be Nothing; skip those.
+    if (II.isNothing())
+      continue;
+
+    // Otherwise, this is a linker input argument.
+    const Arg &A = II.getInputArg();
+
+    // libtool only supports a few of the linker input arguments, warn for the
+    // rest.
+    if (A.getOption().matches(options::OPT_filelist) ||
+        A.getOption().matches(options::OPT_l) ||
+        A.getOption().matches(options::OPT_framework))
+      A.renderAsInput(Args, CmdArgs);
+    else
+      D.Diag(diag::warn_drv_unused_argument) << A.getAsString(Args);
   }
 
   // Delete old output archive file if it already exists before generating a 
new
diff --git a/clang/test/Driver/darwin-static-lib-universal.c 
b/clang/test/Driver/darwin-static-lib-universal.c
new file mode 100644
index 0000000000000..4ad542d4c7700
--- /dev/null
+++ b/clang/test/Driver/darwin-static-lib-universal.c
@@ -0,0 +1,15 @@
+// REQUIRES: system-darwin
+
+// RUN: touch %t1.o %t2.o
+
+// Multiple -arch produces one libtool job per arch plus a lipo. -Xarch_ is 
only
+// forwarded to the matching architecture libtool. 
--static-lib-target-arch-only
+// should pick up the effective triple for each -arch.
+// RUN: %clang -### --emit-static-lib %t1.o %t2.o \
+// RUN:     -arch x86_64 -arch arm64 --static-lib-target-arch-only \
+// RUN:     -Xarch_arm64 --no-static-lib-deterministic \
+// RUN:     -Xarch_x86_64 --static-lib-warn-no-symbols -o libfoo.a 2>&1 \
+// RUN:   | FileCheck %s
+// CHECK: "{{.*}}libtool" "-static" "-arch_only" "x86_64" "-D" "-o" 
"{{.*}}x86_64.out" "{{.*}}1.o" "{{.*}}2.o"
+// CHECK: "{{.*}}libtool" "-static" "-arch_only" "arm64" 
"-no_warning_for_no_symbols" "-o" "{{.*}}arm64.out" "{{.*}}1.o" "{{.*}}2.o"
+// CHECK: "{{.*}}lipo" "-create" "-output" "libfoo.a"
diff --git a/clang/test/Driver/darwin-static-lib.c 
b/clang/test/Driver/darwin-static-lib.c
index 7975d78b7b5f2..4e16e07851b12 100644
--- a/clang/test/Driver/darwin-static-lib.c
+++ b/clang/test/Driver/darwin-static-lib.c
@@ -61,20 +61,35 @@
 // RUN:     -isysroot %S/Inputs/MacOSX15.1.sdk 2>&1 | FileCheck %s 
--check-prefix=ISYSROOT
 // ISYSROOT: "-syslibroot" "{{.*}}MacOSX15.1.sdk"
 
-// -L, -filelist are forwarded as is. -filelist doesn't get doubled up as an 
input file.
+// -L and -F are forwarded in joined format. -iframework is forwarded as -F.
 // -Xstatic-lib-tool passes through.
 // RUN: %clang -target i386-apple-darwin9 -### --emit-static-lib %t1.o %t2.o \
-// RUN:     -L/tmp/first -L/tmp/second -Xstatic-lib-tool -dependency_info 
-Xstatic-lib-tool deps.dat \
-// RUN:     -filelist objs.txt 2>&1 | FileCheck %s --check-prefix=PASSTHROUGH
+// RUN:     -L/tmp/first -L /tmp/second -F/tmp/fw1 -iframework /tmp/ifw -F 
/tmp/fw2 \
+// RUN:     -Xstatic-lib-tool -dependency_info -Xstatic-lib-tool deps.dat 2>&1 
\
+// RUN:   | FileCheck %s --check-prefix=PASSTHROUGH
 // PASSTHROUGH-DAG: "-L/tmp/first" "-L/tmp/second"
+// PASSTHROUGH-DAG: "-F/tmp/fw1" "-F/tmp/fw2" "-F/tmp/ifw"
 // PASSTHROUGH-DAG: "-dependency_info" "deps.dat"
-// PASSTHROUGH-DAG: "-filelist" "objs.txt"
 // PASSTHROUGH-DAG: "{{.*}}1.o" "{{.*}}2.o"
-// PASSTHROUGH-NOT: "-filelist"
 
-// Multiple -arch produces one libtool job per arch plus a lipo.
-// RUN: %clang -target x86_64-apple-macos14 -### --emit-static-lib %t1.o %t2.o 
\
-// RUN:     -arch x86_64 -arch arm64 -o libfoo.a 2>&1 | FileCheck %s 
--check-prefix=UNIVERSAL
-// UNIVERSAL: "{{.*}}libtool" "-static"
-// UNIVERSAL: "{{.*}}libtool" "-static"
-// UNIVERSAL: "{{.*}}lipo" "-create" "-output" "libfoo.a"
+// -filelist, -l, -framework are forwarded (-l in joined format).
+// RUN: %clang -target i386-apple-darwin9 -### --emit-static-lib %t1.o \
+// RUN:     -l foo -filelist first.txt -framework Foo %t2.o \
+// RUN:     -filelist second.txt -lBar 2>&1 \
+// RUN:   | FileCheck %s --check-prefix=LINKER_INPUTS
+// LINKER_INPUTS: "-o" "a.out" "{{.*}}1.o" "-lfoo" "-filelist" "first.txt" 
"-framework" "Foo" "{{.*}}2.o" "-filelist" "second.txt" "-lBar"
+
+// Unsupported linker inputs warn instead of being silently dropped.
+// RUN: %clang -target i386-apple-darwin9 -### --emit-static-lib %t1.o \
+// RUN:     -weak_framework Bar -Xlinker -all_load \
+// RUN:     -rpath /tmp -e _main 2>&1 | FileCheck %s 
--check-prefix=UNSUPPORTED_INPUTS
+// UNSUPPORTED_INPUTS-DAG: warning: argument unused during compilation: 
'-weak_framework Bar'
+// UNSUPPORTED_INPUTS-DAG: warning: argument unused during compilation: 
'-Xlinker -all_load'
+// UNSUPPORTED_INPUTS-DAG: warning: argument unused during compilation: 
'-rpath /tmp'
+// UNSUPPORTED_INPUTS-DAG: warning: argument unused during compilation: '-e 
_main'
+// UNSUPPORTED_INPUTS:     "-static" "-D" "-no_warning_for_no_symbols" "-o" 
"a.out" "{{.*}}1.o"
+// UNSUPPORTED_INPUTS-NOT: "-weak_framework"
+// UNSUPPORTED_INPUTS-NOT: "Bar"
+// UNSUPPORTED_INPUTS-NOT: "-all_load"
+// UNSUPPORTED_INPUTS-NOT: "-rpath"
+

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

Reply via email to