Can I define my binary framework which has open source dependencies without specifying the 'type' parameter in each of my framework's dependencies?

86 views Asked by At

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 add type: .dynamic to the library(name:type:targets:) declaration in the Package.swift file of each of my framework's dependencies. This requires me to fork each of my framework's dependencies and maintain the forks. That's 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."
0

There are 0 answers