From fc4f3e88cfe930410798692049e8628f4dff1cb8 Mon Sep 17 00:00:00 2001 From: Owen Voorhees Date: Tue, 9 Sep 2025 16:19:47 -0700 Subject: [PATCH] Stop passing -framework to libtool The comment on this code was incorrect, as libtool has always ignored the -framework flag, even where a framework contains a static archive --- .../Tools/LinkerTools.swift | 23 +------------------ Tests/SWBCoreTests/CommandLineSpecTests.swift | 1 - ...atureCollectionTaskConstructionTests.swift | 4 ---- .../TaskConstructionTests.swift | 4 +--- 4 files changed, 2 insertions(+), 30 deletions(-) diff --git a/Sources/SWBCore/SpecImplementations/Tools/LinkerTools.swift b/Sources/SWBCore/SpecImplementations/Tools/LinkerTools.swift index 9eacb974..002478c9 100644 --- a/Sources/SWBCore/SpecImplementations/Tools/LinkerTools.swift +++ b/Sources/SWBCore/SpecImplementations/Tools/LinkerTools.swift @@ -1696,28 +1696,7 @@ public final class LibtoolLinkerSpec : GenericLinkerSpec, SpecIdentifierType, @u inputPaths.append(specifier.path) return ["@\(specifier.path.join("args.resp").str)"] - case .framework: - // A static library can build against a framework, since the library in the framework could be a static library, which is valid, and we can't tell here whether it is or not. So we leave it to libtool to do the right thing here. - // Also, we wouldn't want to emit an error here even if we could determine that it contained a dylib, since the target might be only using the framework to find headers. - - // If directed to link it weakly, we emit a warning, since libtool can't perform weak linking (since it's not really linking). Then we pass it normally. - // We silently ignore other non-normal modes, since they are only set programmatically and there's nothing the user can do about them. - if specifier.mode == .weak { - delegate.warning("Product \(cbc.output.basename) cannot weak-link \(specifier.kind) \(basename)") - } - - let frameworkName = Path(basename).withoutSuffix - if specifier.useSearchPaths { - return ["-framework", frameworkName] - } else { - // If we aren't using search paths, we point to the library inside the framework. - // - // FIXME: This is probably a mis-feature, I doubt it is a good idea to bypass the linker's notion of frameworkness. - let frameworkLibraryPath = specifier.path.join(frameworkName) - return [frameworkLibraryPath.str] - } - - case .dynamic, .textBased: + case .dynamic, .textBased, .framework: // A static library can't build against a dynamic library, or against a .tbd file, so we don't add any arguments here. But the inclusion of such a file in the Link Binaries build phase might be used to find implicit dependencies. // We don't have a concrete example of this, and we used to emit an error here, but we removed it in . return [] diff --git a/Tests/SWBCoreTests/CommandLineSpecTests.swift b/Tests/SWBCoreTests/CommandLineSpecTests.swift index 754f3cfc..f902a2dc 100644 --- a/Tests/SWBCoreTests/CommandLineSpecTests.swift +++ b/Tests/SWBCoreTests/CommandLineSpecTests.swift @@ -1520,7 +1520,6 @@ import SWBMacro "-lfoo1", "-lfoo2", Path.root.join("usr/lib/libfoo3.a").str, Path.root.join("usr/lib/libfoo4.a").str, // dylibs are not passed // tbd files are not passed - "-framework", "Foo1", "-framework", "Foo2", Path.root.join("tmp/Foo3.framework/Foo3").str, Path.root.join("tmp/Foo4.framework/Foo4").str, "-o", Path.root.join("tmp/obj/normal/x86_64/output").str]) // FIXME: The input here should really be the link file list. task.checkInputs([ diff --git a/Tests/SWBTaskConstructionTests/SignatureCollectionTaskConstructionTests.swift b/Tests/SWBTaskConstructionTests/SignatureCollectionTaskConstructionTests.swift index 05f2f7fa..d6a9276a 100644 --- a/Tests/SWBTaskConstructionTests/SignatureCollectionTaskConstructionTests.swift +++ b/Tests/SWBTaskConstructionTests/SignatureCollectionTaskConstructionTests.swift @@ -136,8 +136,6 @@ fileprivate struct SignatureCollectionTaskConstructionTests: CoreBasedTests { // Check that there are warnings about trying to weak-link libraries. results.checkWarning("Product libStaticLib1.a cannot weak-link static library libStaticLib2.a (in target 'StaticLib1' from project 'aProject')") - results.checkWarning("Product libStaticLib1.a cannot weak-link framework Framework.framework (in target 'StaticLib1' from project 'aProject')") - results.checkWarning("Product libStaticLib2.a cannot weak-link framework Framework.framework (in target 'StaticLib2' from project 'aProject')") // Check that there are no other diagnostics. results.checkNoDiagnostics() @@ -168,8 +166,6 @@ fileprivate struct SignatureCollectionTaskConstructionTests: CoreBasedTests { // Check that there are warnings about trying to weak-link libraries. results.checkWarning("Product libStaticLib1.a cannot weak-link static library libStaticLib2.a (in target 'StaticLib1' from project 'aProject')") - results.checkWarning("Product libStaticLib1.a cannot weak-link framework Framework.framework (in target 'StaticLib1' from project 'aProject')") - results.checkWarning("Product libStaticLib2.a cannot weak-link framework Framework.framework (in target 'StaticLib2' from project 'aProject')") // Check that there are no other diagnostics. results.checkNoDiagnostics() diff --git a/Tests/SWBTaskConstructionTests/TaskConstructionTests.swift b/Tests/SWBTaskConstructionTests/TaskConstructionTests.swift index 8b9dff5c..a1015a45 100644 --- a/Tests/SWBTaskConstructionTests/TaskConstructionTests.swift +++ b/Tests/SWBTaskConstructionTests/TaskConstructionTests.swift @@ -5038,8 +5038,7 @@ fileprivate struct TaskConstructionTests: CoreBasedTests { // Check that the task contains a command line option to link libStaticLib2.a. task.checkCommandLineContains(["-lStaticLib2"]) - // Check that the task contains a command line option to link Framework.framework. - task.checkCommandLineContains(["-framework", "Framework"]) + // Check that the task does *not* declare libAnotherStatic.a as an input, since it is located via search paths. Some projects may have a file reference whose path does not refer to a file, but which relies on finding the library via search paths anyway. task.checkNoInputs(contain: [.pathPattern(.suffix("libAnotherStatic.a"))]) // Check that the task does *not* declare libStaticLib2.a as an input, since it is located via search paths. Some projects may have a file reference whose path does not refer to a file, but which relies on finding the library via search paths anyway. @@ -5076,7 +5075,6 @@ fileprivate struct TaskConstructionTests: CoreBasedTests { // Check that there are warnings about trying to weak-link libraries. results.checkWarning("Product libStaticLib1.a cannot weak-link static library libStaticLib2.a (in target 'StaticLib1' from project 'aProject')") - results.checkWarning("Product libStaticLib1.a cannot weak-link framework Framework.framework (in target 'StaticLib1' from project 'aProject')") // Check that there are no other diagnostics. results.checkNoDiagnostics()