Android平台openssl编译打包流程

来源:互联网 发布:tensorflow r语言 编辑:程序博客网 时间:2024/06/06 01:05

Android平台openssl编译打包流程

Android从7.0后不支持引用系统Openssl库,对于native开发者,需要将Openssl集成进去,这个过程十分繁琐,整理如下。

准备工作

  • 开发环境 linux ,NDK
  • 代码下载 https://github.com/openssl/openssl
  • 版本选择 笔者以OpenSSL_1_0_2为例,git checkout OpenSSL_1_0_2j
  • 下载环境配置脚本 setenv-android.sh

环境设置

编辑脚本 setenv-android.sh ,分别对两种不同andorid CPU架构进行设置

  • _ANDROID_NDK NDK版本,与NDK路径保持一致
  • _ANDROID_EABI 决定就在NDK中搜索工具的路径
  • _ANDROID_ARCH arch-arm64 / arch-arm 决定了ANDROID_TOOLS的选择
  • _ANDROID_API android-[num]
  • ANDROID_NDK_ROOT=”your ndk root path”
  • ANDROID_TOOL_CHAIN NDK工具链,不用配置,需要输出检验正确性
  • CROSS_COMPILE 输出对应的平台
  • ANDROID_TOOLS 输出对应的编译工具
  • MACHINE aarch64 / armv7

armabi-v7a

  • 默认支持armbi-v7a
  • _ANDROID_EABI=”arm-linux-androideabi-4.9”
  • _ANDROID_ARCH=arch-arm
  • CROSS_COMPILE=”arm-linux-androideabi-“

arm64-v8a

编译该架构的so需要修改Configure、config 以获取对arm64的支持

  • Configure (android-aarch64,android-x86_64)
# Android: linux-* but without pointers to headers and libs."android","gcc:-mandroid -I\$(ANDROID_DEV)/include -B\$(ANDROID_DEV)/lib -O3 -fomit-frame-pointer -Wall::-D_REENTRANT::-ldl:BN_LLONG RC4_CHAR RC4_CHUNK DES_INT DES_UNROLL BF_PTR:${no_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)","android-x86","gcc:-mandroid -I\$(ANDROID_DEV)/include -B\$(ANDROID_DEV)/lib -O3 -fomit-frame-pointer -Wall::-D_REENTRANT::-ldl:BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:".eval{my $asm=${x86_elf_asm};$asm=~s/:elf/:android/;$asm}.":dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)","android-armv7","gcc:-march=armv7-a -mandroid -I\$(ANDROID_DEV)/include -B\$(ANDROID_DEV)/lib -O3 -fomit-frame-pointer -Wall::-D_REENTRANT::-ldl:BN_LLONG RC4_CHAR RC4_CHUNK DES_INT DES_UNROLL BF_PTR:${armv4_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)","android-mips","gcc:-mandroid -I\$(ANDROID_DEV)/include -B\$(ANDROID_DEV)/lib -O3 -Wall::-D_REENTRANT::-ldl:BN_LLONG RC4_CHAR RC4_CHUNK DES_INT DES_UNROLL BF_PTR:${mips32_asm}:o32:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)","android-aarch64","gcc:-march=armv8-a -mandroid -I\$(ANDROID_DEV)/include -B\$(ANDROID_DEV)/lib -O3 -fomit-frame-pointer -Wall::-D_REENTRANT::-ldl:SIXTY_FOUR_BIT_LONG RC4_CHAR RC4_CHUNK DES_INT DES_UNROLL BF_PTR:${aarch64_asm}:linux64:dlfcn:linux-shared:-fPIC::.so","android-x86_64","gcc:-mandroid -I\$(ANDROID_DEV)/include -B\$(ANDROID_DEV)/lib -m64 -DL_ENDIAN -O3 -Wall::-D_REENTRANT::-ldl:SIXTY_FOUR_BIT_LONG RC4_CHUNK DES_INT DES_UNROLL:${x86_64_asm}:elf:dlfcn:linux-shared:-fPIC:-m64:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR):::64",
  • config (android-aarch64,android-x86_64)
  x86-*-android|i?86-*-android) OUT="android-x86" ;;  armv[7-9]*-*-android) OUT="android-armv7" ;;  aarch64-*-android) OUT="android-aarch64";;  x86_64-*-android) OUT="android-x86_64";;

在setenv-android.sh中设置环境变量

  • 在setenv-android.sh 中增加对arch-arm64的分支
case $_ANDROID_ARCH in        arch-arm)      ANDROID_TOOLS="arm-linux-androideabi-gcc arm-linux-androideabi-ranlib arm-linux-androideabi-ld"          ;;        arch-x86)      ANDROID_TOOLS="i686-linux-android-gcc i686-linux-android-ranlib i686-linux-android-ld"          ;;        arch-arm64)      ANDROID_TOOLS="aarch64-linux-android-gcc aarch64-linux-android-ranlib aarch64-linux-android-ld"          ;;        *)          echo "ERROR ERROR ERROR"          ;;
  • 在setenv-android.sh文件最后根据_ANDROID_ARCH设置环境变量,CROSS_COMPILE不能出错
if [ "$_ANDROID_ARCH" == "arch-arm64" ]; then        export MACHINE=aarch64        export RELEASE=2.6.37        export SYSTEM=android        export ARCH=arm64        export CROSS_COMPILE="aarch64-linux-android-"fi
  • _ANDROID_EABI=”aarch64-linux-android-4.9” 对arm64使用aarch64-,这里不能出错,否则会使用错误的工具链

  • _ANDROID_ARCH=arch-arm64 对intel CPU 为x86_64

  • _ANDROID_API=”android-22”
    这里的版本必须要高于19,只用高版本才支持arm64

  • CROSS_COMPILE=”aarch64-linux-android-” 该环境变量必须输出这个结果

  • MACHINE=aarch64

设置Makefile.shared文件,去除so包版本号后缀

  • 干掉软引用
LINK_SO=        \...        $$ALLSYMSFLAGS $$SHOBJECTS $$NOALLSYMSFLAGS $$LIBDEPS \  )# && $(SYMLINK_SO)
# Targets to build symbolic links when neededsymlink.gnu symlink.solaris symlink.svr3 symlink.svr5 symlink.irix \symlink.aix symlink.reliantunix:        @ $(CALC_VERSIONS); \        SHLIB=lib$(LIBNAME).so; \        #$(SYMLINK_SO)
  • 干掉版本后缀
LINK_SO=        \...    LD_LIBRARY_PATH=$$LIBPATH:$$LD_LIBRARY_PATH \    $${SHAREDCMD} $${SHAREDFLAGS} \        -o $$SHLIB$$SHLIB_SUFFIX \        $$ALLSYMSFLAGS $$SHOBJECTS $$NOALLSYMSFLAGS $$LIBDEPS \
DO_GNU_SO=$(CALC_VERSIONS); \...        NOALLSYMSFLAGS='-Wl,--no-whole-archive'; \        SHAREDFLAGS="$(CFLAGS) $(SHARED_LDFLAGS) -shared -Wl,-Bsymbolic -Wl,-soname=$$SHLIB$$SHLIB_SUFFIX"

编译执行

  • make clean 编译一遍后会生成一些中间文件,执行make clean 后会有部分文件(*.S文件)删除不干净,可使用git查看进行手动删除,或者修改对应文件目录下的Makefile文件中的 clean 代码块
clean:        rm -f buildinf.h *.s *.S *.o */*.o *.obj lib tags core .pure .nfs* *.old *.bak fluff        @target=clean; $(RECURSIVE_MAKE)
  • . ./setenv-android.sh 这样写使环境变量生效,相当于source命令

  • ./config shared … 执行config,根据需要增加相关参数选项。这里的shared表示生成.so动态库。在Mac平台上生成.dylib文件

  • make depend 执行config后编译编译模块发生变化,根据上一步输出结果执行

  • vim Makefile (已废弃,不可用)Makefile文件是自动生成的,每次都会更新。默认使用该Makefile编译生成带软引用的.so包(带版本后缀),这种.so在Android中不能被识别。这里修改如下才能生成正常的.so文件

> 在文件中搜索变量 LIBNAME  ,更改为  LIBNAME=$$i\
  • make 开始编译

裁剪测试

  • 编译完会生成 include/ 头文件,libssl.so libcrypto.so,libssl.a libcrypto.a 根据需求集成在自己的项目中
  • 修改 config 参数选可进行裁剪, 点此查看

参考博客:http://blog.csdn.net/liu_lord/article/details/46405287

0 0