Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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!

like image 372
headbanger Avatar asked Dec 06 '25 13:12

headbanger


1 Answers

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.1w openssl-1.1.1w-arm64 
cp -r openssl-1.1.1w openssl-1.1.1w-x86_x64 

Build the Intel half

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

NOTE: For openssl-1.1.1q use -Wno-error=implicit-function-declaration as a configure parameter

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.1w-arm64 
./Configure enable-rc5 zlib darwin64-arm64-cc no-asm
make

NOTE: For openssl-1.1.1q use -Wno-error=implicit-function-declaration as a configure parameter

To create universal binary use command lipo:

cd ..
mkdir openssl-mac
lipo -create openssl-1.1.1w-arm64/libcrypto.a openssl-1.1.1w-x86_x64/libcrypto.a -output openssl-mac/libcrypto.a
lipo -create openssl-1.1.1w-arm64/libssl.a openssl-1.1.1w-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

If you have issues using the library with XCode try to add -lz/-lcrypto into other linker flags (XCode Build settings) if you get compilation errors. Clean build folder after adding this flag.

like image 97
Marek H Avatar answered Dec 09 '25 13:12

Marek H