CocoaPods XCFramework static and dynamic framework error when using Rust to compile iOS and Catalyst libraries

Viewed 583

I am working on an XCFramework that relies on a Rust library I compile and expose to Swift. However, when using that XCFramework inside a CocoaPod which is used as a dependency by another project, I get the following error:

Unable to install vendored xcframework FooFramework for Pod BarProject, because it contains both static and dynamic frameworks.

To clarify a bit what's going on, here's the compilation path beginning with Rust:

Rust Project

In the Rust project, I compile two shared libraries. One for iOS, and one for Mac Catalyst. The iOS library I compile using cargo lipo, with the following command:

cargo clean
cargo lipo --release

Then I just grab the shared library from ./target/universal/release/libfoo.a.

For Catalyst, I have a slightly more involved compilation process, which relies on Rust nightly.

cargo clean
rustup override set nightly
cargo build -Z build-std=panic_abort,std --target x86_64-apple-ios-macabi --release

I then grab the Catalyst library from ./target/x86_64-apple-ios-macabi/release/libfoo.a.

Swift Xcode Projects

Now that I have these two libraries, I actually have two Xcode projects that are fully identical, with the sole exception that they use different library search paths. One project is for iOS and simulator, whereas the other one is just for Mac Catalyst.

The only reason that I have two separate Xcode projects is that I haven't fully figured out how to make the modulemap organization work properly with one project and multiple targets yet, but that, I believe, is beyond the scope of this question.

I generate the iOS and Simulator XCArchives from the iOS project as follows:

xcodebuild archive -scheme FooFramework_iOS -destination "generic/platform=iOS" -archivePath ./FooFramework-iOS SKIP_INSTALL=NO BUILD_LIBRARY_FOR_DISTRIBUTION=YES

xcodebuild archive -scheme FooFramework_iOS -destination "generic/platform=iOS Simulator" -archivePath ./FooFramework-Sim SKIP_INSTALL=NO BUILD_LIBRARY_FOR_DISTRIBUTION=YES

Next, I generate the Catalyst XCArchive:

xcodebuild archive -scheme FooFramework_Mac -destination "platform=macOS,arch=x86_64,variant=Mac Catalyst" -archivePath ./FooFramework-macOS ONLY_ACTIVE_ARCH=YES SKIP_INSTALL=NO BUILD_LIBRARY_FOR_DISTRIBUTION=YES 

Finally, I merge them all into an XCFramework:

xcodebuild -create-xcframework \
-framework ./FooFramework-iOS.xcarchive/Products/Library/Frameworks/FooFramework_iOS.framework \
-framework ./FooFramework-Sim.xcarchive/Products/Library/Frameworks/FooFramework_iOS.framework \
-framework ./FooFramework-macOS.xcarchive/Products/Library/Frameworks/FooFramework_Mac.framework \
-output ./FooFramework.xcframework

For what it's worth, this XCFramework actually works perfectly within regular Xcode projects. However, as soon as it's a dependent Pod's dependency, when compiling that .xcworkspace project, the error I first described appears:

Unable to install vendored xcframework FooFramework for Pod BarProject, because it contains both static and dynamic frameworks.

When I modify the xcodebuild command to create separate *.xcframework files, one for iOS/Sim and the other for Mac, the Pod project compilation immediately starts working.

My question is, how can I generate an XCFramework for iOS/Simulator/Catalyst that will not result in the static/dynamic library error?

0 Answers
Related