'How to build openssl for M1 and for Intel?

I have a project which needs to use Libcrypto - and I have two versions of Libcrypto (libcrypto.a (from OpenSSL 1.1.1) built for ARM64) and (lcrypto.a (from OpenSSL 1.0.2) for Intel). Leaving aside the issues of whether it's good practice or not to have two different versions, I can say that if I include libcrypto.a then I can build and run on M1 and it works fine on M1. If I include lcrypto.a then I can build and run on Intel and it works fine on Intel. What I can't do is include them both (linker error - The linked library 'lcrypto.a' is missing one or more architectures required by this target: arm64.) - and if I can't include them both then I can't build a fat binary, and my app is less than entirely useful!

My question is How can I include both in my project - or where can I get (and how can I include) a fat version of Libcrypto? I've looked at this https://github.com/balthisar/openssl-xcframeworks/releases and this https://developer.apple.com/forums/thread/670631 but I'm none the wiser. I think I built a Fat Binary - but the Fat Binary I thought that I built doesn't work for either architecture!



Solution 1:[1]

Use command lipo to combine binaries

Compile Intel and ARM versions separately (arm version requires Xcode 12).

export MACOSX_DEPLOYMENT_TARGET=10.9
cp -r openssl-1.1.1o openssl-1.1.1o-arm64 
cp -r openssl-1.1.1o openssl-1.1.1o-x86_x64 

Build the Intel half

cd openssl-1.1.1o-x86_x64 
./Configure darwin64-x86_64-cc shared
make

Build the Arm half

export MACOSX_DEPLOYMENT_TARGET=10.15 /* arm64 only with Big Sur -> minimum might be 10.16 or 11.0 */)
cd ../openssl-1.1.1o-arm64 
./Configure enable-rc5 zlib darwin64-arm64-cc no-asm
make

To create universal binary use command lipo:

cd ..
mkdir openssl-mac
lipo -create openssl-1.1.1o-arm64/libcrypto.a openssl-1.1.1o-x86_x64/libcrypto.a -output openssl-mac/libcrypto.a
lipo -create openssl-1.1.1o-arm64/libssl.a openssl-1.1.1o-x86_x64/libssl.a -output openssl-mac/libssl.a

Verify that resulting binary contains both architectures:

file libcrypto.a libssl.a
libcrypto.a: Mach-O universal binary with 2 architectures: [x86_64:current ar archive random library] [arm64]
libcrypto.a (for architecture x86_64):  current ar archive random library
libcrypto.a (for architecture arm64):   current ar archive random library
libssl.a: Mach-O universal binary with 2 architectures: [x86_64:current ar archive random library] [arm64]
libssl.a (for architecture x86_64):  current ar archive random library
libssl.a (for architecture arm64):   current ar archive random library

PS: If you plan to use dynamic library combine dylib files using lipo and run instal_name_tool

cd openssl-mac
install_name_tool -id '@rpath/libcrypto.1.1.1.dylib' libcrypto.1.1.1.dylib
install_name_tool -id '@rpath/libssl.1.1.dylib' libssl.1.1.dylib
otool -D libssl.1.1.dylib /* to verify */

Result:

libssl.1.1.dylib:
@rpath/libssl.1.1.dylib

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1