I've recently converted a bunch of my frameworks to use Swift Package Manager. My Package.swift
looks something like this:
// swift-tools-version:5.1
import PackageDescription
let package = Package(
name: "MDFToolbox",
platforms: [
.macOS(.v10_13), .iOS(.v12), .tvOS(.v12), .watchOS(.v3)
],
products: [
.library(name: "MDFToolbox", targets: ["MDFToolbox"])
],
dependencies: [
.package(url: "[email protected]:Swinject/Swinject.git", from: "2.7.0"),
],
targets: [
.target(name: "MDFToolbox", dependencies: ["Swinject"]),
]
)
Since the library used to be a framework, I'd like to link it in my app as a dynamic library (.dylib
). According to the library product definition in the Package documentation, I can specify the type
of my library to be .dynamic
if I want:
The optional type of the library that is used to determine how to link to the library. Leave this parameter unspecified to let to let the Swift Package Manager choose between static or dynamic linking (recommended). If you do not support both linkage types, use .static or .dynamic for this parameter.
If I leave it as nil
, Xcode defaults to building a static library when I link this package in my app project, which is not what I want.
If I set the type to .dynamic
in my library's Package.swift, Xcode builds a .dylib
, but it doesn't get embedded in the application, leading to a linker error:
dyld: Library not loaded: @rpath/libMDFToolbox.dylib
Referenced from: /Users/mpdifran/Library/Developer/Xcode/DerivedData/Remind-eewbkbjpfrqbdwchjrbmrtxzsjew/Build/Products/Debug-maccatalyst/Remind.app/Contents/MacOS/Remind
Reason: no suitable image found. Did find:
/Users/mpdifran/Library/Developer/Xcode/DerivedData/Remind-eewbkbjpfrqbdwchjrbmrtxzsjew/Build/Products/Debug-maccatalyst/libMDFToolbox.dylib: code signature in (/Users/mpdifran/Library/Developer/Xcode/DerivedData/Remind-eewbkbjpfrqbdwchjrbmrtxzsjew/Build/Products/Debug-maccatalyst/libMDFToolbox.dylib) not valid for use in process using Library Validation: mapped file has no cdhash, completely unsigned? Code has to be at least ad-hoc signed.
I also see no easy way of adding the .dylib
to a Copy Files Build Phase...
So what's the recommended way of asking SPM to build and link a dynamic library through Xcode? Is this something that is not yet supported?
For example the Swift Package Manager prefers to use static linking, but Xcode will try to build SPM packages as dynamic dependencies.
The Swift Package Manager is a tool for managing the distribution of Swift code. It's integrated with the Swift build system to automate the process of downloading, compiling, and linking dependencies.
Dynamic library - . dylib (aka dynamic shared library, shared object, dynamically linked library[doc]) is dynamically linked with the app's executable at load or runtime, but not copied into it. On practice app's package will contain Frameworks folder with . dylib file. All iOS and macOS system libraries are dynamic .
I figured it out!
If you want to create a framework library, you need to force it to be one in the Package.swift
like so:
.library(name: "MDFToolbox", type: .dynamic, targets: ["MDFToolbox"])
Once you've done that, you'll see an embed option in the Xcode project settings of the project linking to the library. When selecting the target, scroll down to the Frameworks, Libraries, and Embedded Content
section. You should see an option to embed your dynamic library dependencies:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With