编译适用arm 架构的so

在 jni 调用 那篇,我们介绍了使用 gcc 编译so 库,但是在Mac 系统下,直接使用默认的gcc 编译so 库,生成的so 文件可能不适合Android 手机的CPU 架构,所以在手机中调用该so 可能会报出如下异常

UnsatisfiedLinkError: dlopen failed: "xxx.so" has bad ELF magic.

这就说明这个so 文件不适合Android CPU,目前市面上的Android 手机的CPU 架构大多为以下几种,

  • arm64-v8a,armeabi-v7a,armeabi,mips,mips64,x86,x86_64

我们对so 文件使用file 命令查看,发现它支持的是x86_64 架构

image.png

而大多数手机都使用的arm 架构,这个时候我们就需要重新编译一个支持arm 架构的so 库。(Android so 库文件头)

主要需要以下工作:

1. 下载Android NDK
只需要通过Android Studio 的SDK Manager 下载即可,

image.png

2. 配置环境变量

export NDK='/Users/whx/Library/Android/android-ndk-r17c'
alias arm-gcc=${NDK}/toolchains/arm-linux-androideabi-4.9/prebuilt/darwin-x86_64/bin/arm-linux-androideabi-gcc

设置环境变量,避免在执行命令的时候输入大量路径字符。

3. 进行编译

1)编译 .c 文件

arm-gcc --sysroot=$NDK/platforms/android-21/arch-arm -isysroot $NDK/sysroot -isystem $NDK/sysroot/usr/include/arm-linux-androideabi -c jbsdiff.c

会生成 .o 文件

2)将 .o 打包成 so 库

arm-gcc --sysroot=$NDK/platforms/android-21/arch-arm -isysroot $NDK/sysroot -isystem $NDK/sysroot/usr/include/arm-linux-androideabi -shared jbsdiff.o jbspatch.o -o libjbsdiff.so

这样就生成了一个 支持 arm 架构的 so 库,可以通过file 命令查看


image.png

这个 so 库就能在arm 架构上的手机正常使用了。

参数说明

--sysroot=
设置编译需要的头文件与库文件的查找目录,会分别查找dir/usr/includedir/usr/lib 目录下的文件

查找头文件

-isysroot directory
设置头文件的查找目录,会查找directory/usr/include。注意,该查找只用于搜索头文件,而且会覆盖上面--sysroot 设置的路径。

-isystem directory
-isysroot 一样,都是设置头文件的查找路径

查找库文件

-Ldirectory
指定库文件查找目录
-lxx.so
指定需要链接的库名

你可能感兴趣的:(编译适用arm 架构的so)