I needed OpenSSL library for the project I've been meaning to start for Apple Watch. So I've checked in all the usual places, and found out that one wasn't made available yet, so I thought I'd take that on myself.
That meant compiling it for watchOS
platform, and four different architectures:
armv7k
and arm64_32
for device, and x86_64
and arm64
for the Simulator.
That last one is a new addition in Xcode 12 to support new M1 Macs. I don't have
one yet, but it would help to prepare for the future.
And that presents first problem. Earlier, before M1 arrived, it was possible
to combine a library built for, say, iOS platform on arm64
architecture with library
built for iOS Simulator on x86_64
into single Mach-O universal binary (or "fat
library"), and Xcode was able to figure out which one goes where, even though
universal binary does not identify platforms for each included architecture.
Now with both M1 and iOS devices running on arm64
architecture, we have two
platforms with the same architecture, and it is not possible to create such universal
binary at all.
So the solution is to create separate "fat libraries" for each individual platform. That means separate library for:
This presents second problem. Previously, you'd just drop single libcrypto.a
(and libssl.a
, if needed) into your project, and call it a day, but now you have to figure
out how to make Xcode use one file, libcrypto-iOS.a
, on device, and another,
libcrypto-iOS-Sim.a
, on Simulator.
Solution to the second problem is new XCFramework
framework format. It combines libraries for all of these platforms (and corresponding
header files) into single directory, and then Xcode magically picks just the right
library automatically. 🎩 It can be easily created using xcodebuild
by passing it a few parameters.
Resulting script is available on GitHub, and there is also a pull request against parent repository. And below is requisite screen shot of OpenSSL library running on watchOS as a proof that it works: