在编译最新的Android OpenSSL之后,我正在尝试构建最新的Android OpenSSL。我设法构建静态库。
然而,我尝试编译共享库。为此,我运行:
./Configure android-armv7 shared
这个编译。问题是,这会创建一个版本化的库,如libssl.so.1.0.0, Android不支持。仅仅重命名是不行的,因为SONAME仍然指向版本化的文件名。
不同的问题是,当我试图创建旧的armeabi平台的库。当我运行:
./Configure android shared
它为旧的armeabi平台创建静态库,而共享库是arm-v7架构。
要构建一个无版本的libcrypto
,覆盖CALC_VERSIONS
是可行的(至少对于1.0.2d):
make CALC_VERSIONS="SHLIB_COMPAT=; SHLIB_SOVER=" all
然后,必须禁用目标install_sw
的子目标link-shared
(否则断开的符号链接会覆盖库),这可以通过在合适的位置创建一个同名的虚拟文件来完成(此外,还必须设置SHLIB_EXT以复制无版本文件)。
我使用的完整bash脚本:
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=<system-specific-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
那么任何生成的目标文件都不应该有或引用一个版本化的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]
如何构建OpenSSL作为未版本的共享库(Android)?
有很多,因为它是一个交叉编译。你应该从这里开始(这是OpenSSL wiki): OpenSSL和Android。
然而,我尝试编译共享库。为此,我运行:
。/配置android-armv7共享
好的,所以你遗漏了一些东西。至少,您应该使用Android NDK。这是AOSP的要求。这些年来,由于使用非ndk工具,我看到了一些小问题。
我相信您需要设置以下环境变量。这是OpenSSL的要求。
- x86:
-
export MACHINE=i686
-
export RELEASE=2.6.37
-
export SYSTEM=android
-
export ARCH=x86
-
export CROSS_COMPILE="i686-linux-android-"
-
手臂:
-
export MACHINE=armv7
-
export RELEASE=2.6.37
-
export SYSTEM=android
-
export ARCH=arm
同时-
:
-
export ANDROID_DEV="$ANDROID_NDK_ROOT/platforms/$_ANDROID_API/$_ANDROID_ARCH/usr"
-
export HOSTCC=gcc
-
ANDROID_DEV
将计算为类似于/opt/android-ndk-r9/platforms/android-14/arch-arm/usr
的值。
您需要提供编译至少一个文件的输出。但我想你也错过了--sysroot
。--sysroot
的参数将类似于/opt/android-ndk-r9/platforms/android-14/arch-arm
。
我建议遵循OpenSSL和Android的说明。指令告诉您要做的第一件事是运行setenv-android.sh
来设置适当的变量。
这是我使用OpenSSL和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
...
您可以忽略Error: FIPS_SIG does not specify incore module...
,因为您不是构建FIPS Capable库。
…未版本的共享库(Android)?
这可能会给你带来麻烦。我认为这样做的方法是为静态库提供一个包装器,并使用您的包装器作为代理。因此,您永远不会使用OpenSSL共享对象,版本控制也无关紧要。
问题是你的进程将从Zygote分叉。Zygote已经将OpenSSL 0.9.8映射到它的空间中。因此,当Zygote为您的进程分叉时,您的进程将已经有0.9.8,并且APK 中的共享对象将不会被映射进去。您只需使用现有的OpenSSL即可。这会导致一些隐晦的问题。
我也相信OpenSSL的Configure
有bug。首先,配置缺少-mfloat-abi=softfp
。这是AOSP的要求。其次,使用-O3
而不是-Os
。这是对资源受限设备的移动需求。
您可能想要打开Makefile
并在配置后进行更改。我在构建库之前也做了同样的事情。