Unable to find auto-linked with SPM

I'm attempting to migrate from an Xcode-based built to SPM. I have a strange setup, which is not under my control. I've got a C-based framework MyPrivateFramework.framework, which contains neither a modulemap nor headers. While these files are not in actually in the .framework container, I have access to the needed .h files.

I've setup a very simple test like this:

MyPrivateFramework/
MyPrivateFramework/Sources/MyPrivateFramework/module.modulemap
MyPrivateFramework/Sources/MyPrivateFramework/MyPrivateFramework.h
MyPrivateFramework/Tests/MyPrivateFrameworkTests/MyPrivateFrameworkTests.swift
MyPrivateFramework/Package.swift

module.modulemap:

module MyPrivateFramework [system] {
  header "MyPrivateFramework.h"
  link framework "MyPrivateFramework.framework"
  export *
}

Package.swift:

import PackageDescription

let package = Package(
    name: "MyPrivateFramework",
    platforms: [.macOS(.v10_15)],
    products: [
        .library(
            name: "MyPrivateFramework",
            targets: ["MyPrivateFramework"]),
    ],
    dependencies: [
    ],
    targets: [
        .systemLibrary(
          name: "MyPrivateFramework"),
        .testTarget(
            name: "MyPrivateFrameworkTests",
            dependencies: ["MyPrivateFramework"],
            
            linkerSettings: [
              .unsafeFlags(["-F", "/path/to/framework/parent/directory"]),
            ]),
    ],
    swiftLanguageVersions: [.v5]
)

The goal of this is just to ensure that I can successfully access the functions with MyPrivateFramework. I thought was re-creating the same configuration as what I'm using within my Xcode target, but this setup fails to link with:

ld: warning: Could not find or use auto-linked framework 'MyPrivateFramework.framework'

I've tried every combination I can think of for linkerSettings, but it seems that nothing I can do will allow the linker to find the framework. Anyone have any ideas on how I might get this to work with SPM?

By default, Xcode will not build a framework for a library product. You have to explicitly ask for that by specifying it as dynamic (see Apple Developer Documentation).

1 Like

Thanks for this information. That's interesting, as my Xcode-based version builds what I need as a static lib without issue.

I did what I think you were suggesting, adding a .type parameter to my one .library entry. It produces a new, different error:

error: system library product MyPrivateFramework shouldn't have a type and contain only one target

Did I make the change you intended?

Just got off a call with some helpful folks from a Swift lab. They were able to come up with a solution that worked, and I figured I would post the solution.

The key was passing in correct linker flags:

.unsafeFlags(["-Xlinker", "-F", "-Xlinker", "/path/to/framework/parent/directory", "-Xlinker", "-framework", "-Xlinker", "MyPrivateFramework"]),