2

I'm having a problem defining the Package.swift file for my binary closed-source dynamic framework which depends on a number of non-binary open-source dynamic frameworks.

My Package.swift file looks like this:

// swift-tools-version: 5.8
// The swift-tools-version declares the minimum version of Swift required to build this package.

import PackageDescription
import Foundation

let package = Package(
    name: "MyLibrary",
    platforms: [
        .iOS(.v12)
    ],
    products: [
        .library(
            name: "MyLibrary",
            targets: ["MyLibraryWrapper"]
        ),
    ],
    dependencies: [
        .package(url: "<dependency-url>", branch: "master"),
    ],
    targets: [
        .target(
            name: "MyLibraryWrapper",
            dependencies: [
                .target(name: "MyLibrary"),
                .product(name: "<dependency-product-name>", package: "<dependency-package-name>")
            ],
            path: "MyLibraryWrapper"
        ),
        .binaryTarget(
            name: "MyLibrary",
            url: "<url-to-xcframework-zip>",
            checksum: "<checksum>"
        )
    ]
)

The package builds successfully. However, when I add it to any app, I get the following runtime error:

Library not loaded: @rpath/<dependency-product-name>.framework

The only workaround I know is to fork the source project of each of my framework's dependencies and to declare the type of each library as .dynamic. This requires me to maintain a fork for each of my framework's dependencies. This is not something I'm keen on.

Is there is a better, simpler solution to this problem?

Notes

  1. I need to declare the MyLibraryWrapper target in my Package.swift file because the binaryTarget(name:url:checksum:) method does not offer a dependencies parameter.
  2. The MyLibraryWrapper directory which the MyLibraryWrapper target declares as its path contains a single empty source file and nothing else.
  3. I tried declaring the type of MyLibrary as .dynamic via the library(name:type:targets:) method. I was hoping that Swift Package Manager would do the right thing of dynamically linking MyLibrary and its dependencies. Sadly, declaring the type of MyLibrary as .dynamic results in a "Multiple commands produce MyLibrary.framework" build error.
  4. The non-binary dynamic frameworks which MyLibrary depends on do not specify an explicit type value in their Package.swift files. This is based on Apple's recommendation in the library(name:type:targets:) method documentation: "It’s recommended that you don’t explicitly declare the type of library, so Swift Package Manager can choose between static or dynamic linking based on the preference of the package’s consumer."
1
  • No. Sadly, we have to maintain a fork of each of our framework's dependencies as you can see in the dependencies array in this Package.swift file. We haven't found a better solution. Commented May 6, 2024 at 11:05

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.