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
