Headers not found for an XCFramework packaging a static lib for iOS (critical)

With Xcode and frameworks it has been possible to wrap a static library, and have a framework statically link with that library. A good example would be an Objective-C wrapper for a C++ library.

I have been trying to accomplish such a thing with a Swift Package, and it seemed easy but I believe there might be a bug in SPM. Or I am doing something wrong but can't figure it out.
I pushed an example here https://github.com/quentinfasquel/MyDependencySample

  • Packaging a static library along with its headers as an XCFramework is easy (using binaryTarget)

1- Using that library in a Swift Package and have it build is easy

2- Using that Swift Package in an app will not work as this Swift Package won't be able to compile.Somehow the XCFramework's headers don't seem to be found.

3- Manually dragging the .xcframework in your final target solve the issue (sometimes) but I find it inconvenient and not ideal to have a reference to "BUILD_PRODUCT/../../Package.."

4- Adding a product to the Swift Package for the binaryTarget and add that product to the final app target fixes the problem but does something not-OK : export libMyCppLibrary.a into the app bundle's Frameworks directory... that should never happen.

5- Also, back to the Swift Package outside an app, trying to archive it will not work and trigger the same "header not found" issue.

In need of help, or an official saying that this is a bug.

1 Like

It does this for ALL dynamic Swift Package libraries. Really damn annoying. Anyone know a workaround?

There's a workaround with Xcode, a bit disappointing but it does the trick.. a script phase that removes the files that shouldn't be there.

Hey @quentinfasquel - I think I'm in a very similar boat. Were you ever able to get a static lib working as part of a Swift Package?

I've written a small lib in Golang and used go build --buildmode=c-archive which creates my header and archive file. I then packaged this into an XCFramework bundle using xcodebuild -create-xcframework -library {.a} -headers include -output {outfile}

I dropped this bundle in my Swift library project, along with a module.modulemap file in the same dir, where I have:

module {module_name} {
header "{.xcframework/path_to_header}"
export *
}

Where .xcframework is the actual bundle, followed by the path directly to the header file (in my case, I'm only building for macOS at the moment, so I'm pointing directly to the macos-x86_64 archtype).

Finally, in my Package.swift, I have a .binaryTarget entry whose path points to the above .xcframework file. I also had to include this section in the actual lib target:

cSettings: [
.headerSearchPath({relative_path_to_parent_folder_containing_modulemap}),
]

In all my searching, it seems like using headerSearchPath isn't very common - I don't know why I need it, but I digress. The fact is...this all compiles fine with swift build, and in fact my main class is able to import the aforementioned module AND I can access the method(s) exposed as defined by the header file. In other words...seems great, no?

Problem is - despite it compiling, when I pull it in as a Swift Package Dependency in my actual app (using the remote option - I have this all up on git), and I try to import it - the actual import name is found, but it gives me an error saying: "Missing required module '{module}'" - where module matches the name I defined in the modulemap file.

For what it's worth, I was actually able to get the app project working when the header/lib source was locally in the project itself, using a similar module.modulemap file and some small tweaks in the build settings (i.e. updating the Swift Compiler Import Paths and Library Search Paths to point to $(SRCROOT) which is required for it to pick up the modulemap). Unfortunately it all broke when I used Swift Package Manager to pull in some other remote dependencies. It seems like once I added those, it stopped honoring the import/search paths. I don't have a strict requirement for this static lib to be a remote package or xcframework bundle - but I couldn't figure out a workaround after introducing the remote dependencies.

Exact same boat... and the boat is still rocking.

exactly the same problem, few hours on this :sleepy:

Terms of Service

Privacy Policy

Cookie Policy