一、so文件的概念

通常情况下,对函数库的链接是放在编译时期(compile time)完成的。所有相关的对象文件(object file)与牵涉到的函数库(library)被链接合成一个可执行文件(executable file)。程序在运行时,与函数库再无瓜葛,因为所有需要的函数已拷贝到自己门下。所以这些函数库被成为静态库(static libaray),通常文件名为“libxxx.a”的形式。

其实,我们也可以把对一些库函数的链接载入推迟到程序运行的时期(runtime)。这就是如雷贯耳的动态链接库(dynamic link library)技术,通常文件名为“libxxx.so”的形式。

二、Android引入so文件的作用

开发Android应用时,有时候Java层的编码不能满足实现需求,就需要到C/C++实现后生成SO文件,再用System.loadLibrary()加载进行调用,这里成为JNI层的实现。常见的场景如:加解密算法,音视频编解码等。在生成SO文件时,需要考虑适配市面上不同手机CPU架构,而生成支持不同平台的SO文件进行兼容。目前Android共支持七种不同类型的CPU架构,分别是:ARMv5,ARMv7 (从2010年起),x86 (从2011年起),MIPS (从2012年起),ARMv8,MIPS64和x86_64 (从2014年起)。

三、现有的常用ABI

应用程序二进制接口(Application Binary Interface)定义了其所对应的CPU架构能够执行的二进制文件(特别是.so文件)的格式规范。在Android系统上,不同 Android 手机使用不同的 CPU,因此支持不同的指令集。CPU 与指令集的每种组合都有其自己的应用二进制界面(或 ABI)。 ABI 可以非常精确地定义应用的机器代码在运行时如何与系统交互。 您必须为应用要使用的每个 CPU 架构指定 ABI:armeabi,armeabi-v7a,x86,mips,arm64-v8a,mips64,x86_64。

典型的 ABI 包含以下信息:

(1)、机器代码应使用的 CPU 指令集。
(2)、运行时内存存储和加载的字节顺序。
(3)、可执行二进制文件(例如程序和共享库)的格式,以及它们支持的内容类型。
用于解析内容与系统之间数据的各种约定。这些约定包括对齐限制,以及系统如何使用堆栈和在调用函数时注册。
(4)、运行时可用于机器代码的函数符号列表 - 通常来自非常具体的库集。
(5)、支持一个或多个指令集。

四、SO(CPU)的兼容

每一个CPU架构对应一个ABI,一个cpu属于某一种架构,多核cpu需要属于相同架构才能一起工作,很多设备仅支持一种的CPU架构。

如果你要完美兼容所有类型的手机,理论上是要在的libs目录下放置各个架构平台的SO文件。