I am trying to build the latest OpenSSL for Android following Compiling the latest OpenSSL for Android. I manage to build the static libs.
However I try to compile the shared libs. To do so I run:
./Configure android-armv7 shared
This compiles. Problem is that this creates a versioned lib like libssl.so.1.0.0, which is not supported by Android. Just rename does not do because of SONAME is still pointing to the versioned filename.
Different problem I have is when trying to the create the libs for old armeabi platform. When I run:
./Configure android shared
it creates the static libs for the old armeabi plattform, the shared libs however are arm-v7 architecture.
As to build a version-less libcrypto
, overwriting CALC_VERSIONS
does the trick (at least for 1.0.2d):
make CALC_VERSIONS="SHLIB_COMPAT=; SHLIB_SOVER=" all
Then, the sub-target link-shared
of the target install_sw
must be disabled (otherwise broken symlinks overwrite the libraries), which can be done by creating a dummy file of the same name at the suitable place (furthermore, SHLIB_EXT must also be set for the version-less files to be copied).
The complete bash-script I used:
ORIG_PATH=$PATH SCRIPT_PATH=$(dirname $(readlink -f $0)) tar -zxf $SCRIPT_PATH/openssl-fips-2.0.10.tar.gz tar -zxf $SCRIPT_PATH/openssl-1.0.2d.tar.gz ANDROID_NDK_PATH=/android-ndk-r10e-linux ANDROID_API=android-14 ANDROID_SYSROOT=$ANDROID_NDK_PATH/platforms/$ANDROID_API/arch-arm export OPENSSLDIR=$SCRIPT_PATH/ssl/android/arm export FIPSDIR=$OPENSSLDIR/fips-2.0 export HOSTCC=gcc export FIPS_SIG=$SCRIPT_PATH/openssl-fips-2.0.10/util/incore export ANDROID_DEV=$ANDROID_SYSROOT/usr export PATH=$ANDROID_NDK_PATH/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin:$ORIG_PATH export MACHINE=armv7 export RELEASE=2.6.37 export SYSTEM=android export ARCH=arm export CROSS_COMPILE=arm-linux-androideabi- cd $SCRIPT_PATH/openssl-fips-2.0.10 ./config shared make clean make make install_sw cd $SCRIPT_PATH/openssl-1.0.2d ./config fips shared -no-sslv2 -no-sslv3 -no-comp -no-hw -no-engines --openssldir=$OPENSSLDIR --with-fipsdir=$FIPSDIR --with-fipslibdir=$FIPSDIR/lib/ make clean make depend make CALC_VERSIONS="SHLIB_COMPAT=; SHLIB_SOVER=" MAKE="make -e" all mkdir -p $OPENSSLDIR/lib echo "place-holder make target for avoiding symlinks" >> $OPENSSLDIR/lib/link-shared make SHLIB_EXT=.so install_sw rm $OPENSSLDIR/lib/link-shared
Then no generated object file should have or reference a versioned so-name:
$ readelf -d ssl/android/arm/lib/libcrypto.so | grep 'SONAME\|NEEDED' 0x00000001 (NEEDED) Shared library: [libdl.so] 0x00000001 (NEEDED) Shared library: [libc.so] 0x0000000e (SONAME) Library soname: [libcrypto.so] $ readelf -d ssl/android/arm/lib/libssl.so | grep 'SONAME\|NEEDED' 0x00000001 (NEEDED) Shared library: [libcrypto.so] 0x00000001 (NEEDED) Shared library: [libdl.so] 0x00000001 (NEEDED) Shared library: [libc.so] 0x0000000e (SONAME) Library soname: [libssl.so] $ readelf -d ssl/android/arm/bin/openssl | grep 'SONAME\|NEEDED' 0x00000001 (NEEDED) Shared library: [libssl.so] 0x00000001 (NEEDED) Shared library: [libcrypto.so] 0x00000001 (NEEDED) Shared library: [libdl.so] 0x00000001 (NEEDED) Shared library: [libc.so]
How to build OpenSSL as unversioned shared lib (for Android)?
There's a lot to it because its a cross compile. You should probably start here (its the OpenSSL wiki): OpenSSL and Android.
However I try to compile the shared libs. To do so I run:
./Configure android-armv7 shared
Ok, so you are missing a few things. At minimum, you should be using the Android NDK. This is a requirement from AOSP. I've seen a number of little problems over the years due to using non-NDK tools.
And I believe you need the following environmental variables set. This is an OpenSSL requirement.
x86:
export MACHINE=i686
export RELEASE=2.6.37
export SYSTEM=android
export ARCH=x86
export CROSS_COMPILE="i686-linux-android-"
ARM:
export MACHINE=armv7
export RELEASE=2.6.37
export SYSTEM=android
export ARCH=arm
Both:
export ANDROID_DEV="$ANDROID_NDK_ROOT/platforms/$_ANDROID_API/$_ANDROID_ARCH/usr"
export HOSTCC=gcc
ANDROID_DEV
will evaluate to something like /opt/android-ndk-r9/platforms/android-14/arch-arm/usr
.
You need to provide the output of compiling at least one file. But I expect you are missing --sysroot
too. The argument to --sysroot
will be something like /opt/android-ndk-r9/platforms/android-14/arch-arm
.
I would recommend following the instructions at OpenSSL and Android. The first thing the instructions tell you to do is run setenv-android.sh
to set the proper variables.
Here's what my run looks like using OpenSSL and Android.
$ cd openssl-1.0.1h $ . ./setenv-android.sh Error: FIPS_SIG does not specify incore module. Please edit this script. ANDROID_NDK_ROOT: /opt/android-ndk-r9 ANDROID_EABI: arm-linux-androideabi-4.6 ANDROID_API: android-14 ANDROID_SYSROOT: /opt/android-ndk-r9/platforms/android-14/arch-arm ANDROID_TOOLCHAIN: /opt/android-ndk-r9/toolchains/arm-linux-androideabi-4.6/prebuilt/darwin-x86_64/bin FIPS_SIG: CROSS_COMPILE: arm-linux-androideabi- ANDROID_DEV: /opt/android-ndk-r9/platforms/android-14/arch-arm/usr $ ./config shared no-ssl2 no-ssl3 no-comp no-engines no-hw no-psk no-srp Operating system: armv7-whatever-android Configuring for android-armv7 Configuring for android-armv7 no-comp [option] OPENSSL_NO_COMP (skip dir) no-ec_nistp_64_gcc_128 [default] OPENSSL_NO_EC_NISTP_64_GCC_128 (skip dir) no-engines [option] OPENSSL_NO_ENGINES (skip dir) ... no-srp [option] OPENSSL_NO_SRP (skip dir) no-ssl2 [option] OPENSSL_NO_SSL2 (skip dir) no-ssl3 [option] OPENSSL_NO_SSL3 (skip dir) no-store [experimental] OPENSSL_NO_STORE (skip dir) no-zlib [default] no-zlib-dynamic [default] IsMK1MF=0 CC =gcc ... $ make ... arm-linux-androideabi-gcc -I. -I.. -I../include -fPIC -DOPENSSL_PIC -DOPENSSL_THREADS -D_REENTRANT -DDSO_DLFCN -DHAVE_DLFCN_H -Wa,--noexecstack -march=armv7-a -mandroid -mfloat-abi=softfp -I/opt/android-ndk-r9/platforms/android-14/arch-arm/usr/include -B/opt/android-ndk-r9/platforms/android-14/arch-arm/usr/lib -Os -fomit-frame-pointer -Wall -DOPENSSL_BN_ASM_MONT -DOPENSSL_BN_ASM_GF2m -DSHA1_ASM -DSHA256_ASM -DSHA512_ASM -DAES_ASM -DGHASH_ASM -c -o cryptlib.o cryptlib.c ...
You can ignore Error: FIPS_SIG does not specify incore module...
because you are not building a FIPS Capable library.
... unversioned shared lib (for Android)?
This will probably get you in trouble. I believe the way to do it is to provide a wrapper around the static lib, and use your wrapper as a surrogate. So you never use the OpenSSL shared object, and versioning does not matter.
The problem is your process will fork from Zygote. Zygote already has OpenSSL 0.9.8 mapped into its space. So when Zygote forks for your process, your process will already have 0.9.8 and the shared object in your APK will not be mapped in. You will simply use the existing OpenSSL. That will lead to obscure problems.
I also believe there are bugs in OpenSSL's Configure
. First, the configuration is missing -mfloat-abi=softfp
. That's an AOSP requirement. Second, -O3
is used rather than -Os
. That's a mobile requirement on resource constrained devices.
You might want to open Makefile
and make the changes after you configure. I do the same before I build the library.