xcframework: how to wrap a static library?

This topic was touched on in the notes for the WWDC 2019 session on Binary Frameworks - I even watched the whole video but it wasn't covered there.


It appears I should be able to wrap a static library - one that is created by its own (complex) build scripts - and have iOS, iOS Simulator and macOS versions. Also, that the header files can be included as well.


I have been unable to find any information googling around on how one might do this. I would greatly appreciate any pointers to some blog/post that covers this.


Thanks!

Post not yet marked as solved Up vote post of dhoerl Down vote post of dhoerl
12k views

Replies

You should be able to wrap it in a framework and expose the API in the framework header. You may need to use the -all_load or -force_load linker flags, but test it first.

You need this incantation of xcodebuild:

xcodebuild -create-xcframework -library <path> [-headers <path>] [-library <path> [-headers <path>]...] -output <path>

Xcode Help contains several build steps you need to perform before needing the above command.

Thank you so much for this! One question - does xcodebuild examine each library to determine what architecture (and in the case of x86/arm) determine what the target device is? So no need for some manifest telling it this info I guess.


Again - thanks so much!

xcodebuild determines this based on the -destination option. In general, you can't assume anything from just the CPU architecture. For example, an iOS Simulator binary is compiled with slightly different options than a Mac Catalyst binary, and those binaries aren't interchangeable even though they both use the x86_64 CPU architecture.

xcodebuild determines this based on the -destination option.

How do we apply this when a static library is not built with Xcode? I have a static library (in C) built for several architectures, but I haven't found any way to build an xcframework that associates the correct architecture with the simulator. When I try to construct an xcframework just by appending them all:
Code Block
for lib in *.a; do xcodebuild -create-xcframework -library $lib -headers include -output PEQ.xcframework; done

the linking product that consumes them throws a warning:
Code Block
ld: warning: ignoring file .../Release-iphonesimulator/PEQ-x86_64.a, missing required architecture arm64 ...

And cannot find the symbols. I've also tried linking just the x86_64 and arm64 versions in a single call:
Code Block
xcodebuild -create-xcframework -library PEQ-arm64.a -headers include -library PEQ-x86_64.a -headers include -output PEQ.xcframework

(If I try to include the i386 or armv7 versions, it complains that they "represent two equivalent library definitions")

There is no xcodeproj for these static libraries. They are proprietary and do not even have source code for them. How do I associate the correct static library with each platform and simulator?

@dhoerl, this seems to be very similar to your issue (in that the libraries are built outside of Xcode), so did this solution work?

Note that I don't actually care about creating an xcframework. I don't need to distribute this framework. I'm just trying to link existing static libraries into our application, and have it work on device and simulator.
  • did you found any solution to this?

  • rofl, hey let us know if you get a solution implemented

Add a Comment
@robnapier - I never completed this - a job came up and I never swung back. It was/is for one of my open source projects. Like you 3rd party binary.

I don't know why Apple is absolutely no help or instruction regarding this issue, but you must use lipo to make fat binaries, one for each platform. Details https://developer.apple.com/forums/thread/666335?answerId=685927022#685927022.

faced the same issue while converting binaries to xcframework, it says could not find the target [platform]( https://www.example.com/)

Well hit this problem again at a new job. Cannot run app on Simulator because a binary .a from a 3rd party won't link. Sigh. And nothing from Apple :-(