Static libraries into XCFramework

I have number of static libraries, all of them build as a fat library (arm64, x86_64 are architectures).

I'm implementing dynamic framework that works with these libraries. They are added into the frameworks with

As a requirement from a client comes to have also XCFramework. XCFramework is created successfully but only if EXCLUDED_ARCHS flag is set to YES in Simulator build script. If NO this is the error I'm getting:

... building for iOS Simulator, but linking in object file built for iOS, for architecture arm64.

So is this a good approach or could be done better? I've learned today about --library flag on -create-xcframework but don't know whether they fit in my case.

Also I was thinking to create XCFramework with static libraries and include it in my library. How about this option?

Any advice will be helpful 👍

P.S My framework supports iOS 11, does this mean that I need to have version for armv7 in the static library?

Answered by DTS Engineer in 671325022
The right way to do this is starting with your Xcode project and running it through the archive process, with additional build settings enabled. Please see the documentation for the exact commands and settings.

When building a XCFramework, regardless if it contains a framework or a static library, you should never need to call lipo. Needing to do so is an indication that you're not following the command recipe in that document. Since this discussion started with questions about architecture build settings, you should also make sure that these settings are all the default values. If you're not sure, make a new Xcode project to look at how those settings are configured by default, and adjust your project's settings to the same.
You shouldn't set EXCLUDED_ARCHS, that indicates there's something else wrong here. Let's back up a level to the static libraries, since it sounds like that's what is incorrectly driving you down this path.

... building for iOS Simulator, but linking in object file built for iOS, for architecture arm64.

This makes it sound like your static libraries are incorrectly built. Having x86_64 and arm64 in the same binary file is only ok if both of those architectures are intended for the iOS Simulator, with the arm64 version new to supporting the iOS Simulator on Macs with Apple silicon chips. If x86_64 is for the simulator, and arm64 is for a device, that's never been a supported configuration, and will generate the quoted error message in recent Xcode versions. If that's the case, either the static libraries should be directly linked to your framework from source. If they need to be pre-built, then all of these libraries must first be pre-built into an XCFramework using the --library and --header options, and your framework then consumes the static library from these XCFrameworks.

iOS 10 was the last iOS version that supported 32-bit architecture, so you don't need to support armv7. That said, you shouldn't explicitly configure this, Xcode will just not produce armv7 if the deployment target is iOS 11 or higher.
Hi, thanks for the response at first.

I've followed your advice and created separate XCFramework for every static library. This is a structure I'm having:
Code Block
- libStatic.xcframework:
- Info.plist
- ios-arm64
- libStatic.a
- ios-x86_64-simulator
- libStatic.a

I don't include headers and leave it into the framework, because the library have so many C files and it is hard for me process which header belongs to concrete lib(Will try to fix that, could this leads to issue?)

Unfortunately here comes another issue. I've set ONLY_ACTIVE_ARCH to NO as I think the value should be(Is that correct by the way?) and there are warning and an error:

First the warning:
Code Block
ignoring file libstatic.a, building for iOS Simulator-arm64 but attempting to link with file built for iOS Simulator-x86_64


Then the error:

Code Block
Undefined symbols for architecture arm64:
  "_RAND_seed", referenced from:

Which leads me to conclusion, that there is no support for arm64 simulator. I've tried to add a arm64 simulator binary, but in the xcframework generation comes this error:

Code Block
Both ios-x86_64-simulator and ios-arm64-simulator represent two equivalent library definitions.


I was reading, that in this case we need to create fat binary with both arm64 and simulator slices.

Also was thinking should DTS be created for that.




ONLY_ACTIVE_ARCH should be set to NO for the release build, since that's what creating an XCFramework should be — a release build of the static library built for all supported architectures of the target platform.

Is this static library one you or your company wrote, or is it from a third-party vendor? If it's one you control, we'll be happy to help you through a DTS TSI. However, if it's not one you control, you should seek support from the vendor, since they will have the most detailed knowledge of what architectures their library currently supports, as well as which header files to include.
Accepted Answer
Yes, we are developing the static libraries, so it is good to know, that we can do that.

We've managed to create successful build, I will not do a DTS, but will post my solution and if possible will love some feedback from you @edford:

Here is a small script I've created. It presumes, that static libs for a given platform are already put into the corresponding directories
Code Block shell
#!/bin/bash
rm -rf output/
rm -rf simulator_fat/
mkdir simulator_fat
libs=( "lib_static" ) #Add
for i in "${libs[@]}"
do
lipo -create arm64_simulator/$i.a x86_64/$i.a -output simulator_fat/$i.a
xcodebuild -create-xcframework -library simulator_fat/$i.a -library arm64/$i.a -output output/$i.xcframework
done


The XCFramework now has the following structure:
Code Block
lib_static.xcframework:
- Info.plist
- ios-arm64_x86_64-simulator
- lib_static.a #This is the fat lib I mentioned
- ios-arm64
- lib_static.a


In that way ONLY_ACTIVE_ARCH and EXCLUDED_ARCHS are not problem anymore.

Thanks a lot @edford




The right way to do this is starting with your Xcode project and running it through the archive process, with additional build settings enabled. Please see the documentation for the exact commands and settings.

When building a XCFramework, regardless if it contains a framework or a static library, you should never need to call lipo. Needing to do so is an indication that you're not following the command recipe in that document. Since this discussion started with questions about architecture build settings, you should also make sure that these settings are all the default values. If you're not sure, make a new Xcode project to look at how those settings are configured by default, and adjust your project's settings to the same.
Static libraries into XCFramework
 
 
Q