How to build an XCFramework from a Swift Package (with Resources)

I have some code that is currently built using Swift Package Manager. It does not have an Xcode project. I want to build an XCFramework from my package, but when I build the package it creates a .o, and xcodebuild -create-xcframework does not seem to support .o files.

Also, I have added resources, and now I see there is a .bundle, but I don’t see any way to add the .bundle to an XCFramework.

I have tried changing my Package.swift library product to be .dynamic (even though I prefer it to be .static), and that produces a .framework, which I can then convert to an XCFramework, but it does not appear to have my resources (they appear to still be in the .bundle file next to my .o).

I have also tried making an Xcode project to wrap my Swift package. It imports my package and links against it and produces a Framework that I can make an XCFramework from, but it also does not have my Resources.

All of this was done using Xcode 12 beta.
Answered by Developer Tools Engineer in 614003022
While creating XCFrameworks from Swift packages may work in some limited cases, we don't support it today. Using an Xcode target to wrap a package also will not work, because an XCFramework bundles a single module, but in this case you would have two.

You will have to manually create a Xcode project for your library in order to create an XCFramework for it.

For context, what's your use case for doing this? Are you developing a closed source library as a package and now you want to distribute it as an XCFramework to clients?
Accepted Answer
While creating XCFrameworks from Swift packages may work in some limited cases, we don't support it today. Using an Xcode target to wrap a package also will not work, because an XCFramework bundles a single module, but in this case you would have two.

You will have to manually create a Xcode project for your library in order to create an XCFramework for it.

For context, what's your use case for doing this? Are you developing a closed source library as a package and now you want to distribute it as an XCFramework to clients?
The short answer of the use case is to break up a very large app (at Amazon) and not have to compile the entire thing from source.

We have already been doing this by using the old Xcode project generator (although I’ve made modifications to it). With that we can create XCFrameworks. In my modifications to the Xcode project generator, I actually implemented support for resources and binary artifacts, modeling after the Swift Evolution documents. We’ve taken advantage of the SPM mirroring feature to mirror our own urls with mirrored packages that point to the binary XCFrameworks that we have built (mirroring source code with prebuilt binary).

This has obviously required a lot of customization on our part, and I was hoping to do away with that, but it looks like I still need to keep waiting, especially since the new resources and binary artifact support was only implemented via Xcode integration, and not via the old Xcode project generator tool.

I scheduled a session tomorrow, so hopefully I can go over more specifics then. I know I’m not going to get everything I want this year, but I’m glad to see all the progress that continues to be made on SPM.
Here is essentially the strategy:

Say we have 2 packages:
http://example.com/PackageA
http://example.com/PackageB

We have a CI tool that builds PackageB and saves PackageB.xcframework somewhere: http://example.com/prebuilt/PackageB

The prebuilt PackageB has its own Package.swift, with a binary target instead of a source target: .binaryTarget(“PackageB”, url: “http://example.com/prebuilt/PackageB”)

So then for PackageA, we can
swift package set-mirror —package-url “http://example.com/PackageB” —mirror-url “http://example.com/prebuilt/PackageB”

Then voila, PackageA now has a precompiled PackageB artifact instead of building it from source.

We are already doing this, because of my own modifications to pbxproj().swift in SPM, but I’m hoping to get rid of that.
Thanks for explaining, this is a use case we explicitly deferred for the current binary dependencies proposal. Your use case is the artifact cache one, but we only set out to solve vendored binaries for now.
Yes, I was aware of that proposal, but I was hoping I could make XCFrameworks from my packages and not have to wait for the full implementation of that proposal. But I guess that not the case. I will continue to wait patiently. Thank you for the quick responses.
Did you ever find a way to include a .bundle into your XCFramework? I've been trying to include an asset catalog with our XCFramework but I've so far had no success.
@rvenable is your fork of SPM open source by any chance? I'm facing the same issue at the moment.
How to build an XCFramework from a Swift Package (with Resources)
 
 
Q