JNI开发之打包输出so库

来源:互联网 发布:软件开发收费标准 编辑:程序博客网 时间:2024/05/16 07:24
首先要明白ABI的概念:
ABI(Application Binary Interface)实际就是指应用程序基于哪种指令集来进行编译,我们能用到的ABI 也就四种  armeabi armeabi-v7a x86 和mips ,前两者是最常见的。

其次这4个编译选项的含义:
1.‘armeabi’ – 默认选项,将创建以基于 ARM* v5TE 的设备为目标的库。 具有这种目标的浮点运算使用软件浮点运算。 使用此 ABI 创建的二进制代码将可以在所有 ARM* 设备上运行。
2.‘armeabi-v7a’ – 创建支持基于 ARM* v7 的设备的库,并将使用硬件 FPU 指令。
3.‘x86’ – 生成的二进制代码可支持包含基于硬件的浮点运算的 IA-32 指令集.
4.mips — 支持应用二进制接口


总结:
APP_ABI 赋值,就是为了交叉编译生成相应芯片可执行的指令集。
在jni目录新建Application.mk 写入: APP_ABI := armeabi armeabi-v7a mips x86  那么在你的android工程下边的 libs 里边会出现 armeabi armeabi-v7a mips x86 这四个目录下会分别生成 4个.so文件。程序在Android手机运行时,根据手机自身CPU芯片不同,去选择调用相应的.so文件。需要注意的是选择的平台越多,so库也越多,打包的apk体积也越大。这点与iOS打包有点类似。

在编译的时候你可以指定其中的一种或者几种,如果指定了几种,这时候打包到APK后这个APK被称为“胖二进制”,也就是它包含了几种ABI类型的lib
当APK被安装到设备上的时候,android系统有这样一个机制:
系统支持哪些ABI类型它自己是知道的,它们会将最适合机器性能发挥的ABI类型标记位'primary' 把剩下的也支持的标记为‘secondary’。例如:
应用程序安装的时候系统首先检查lib/<primary-abi>/libxx.so 如果有的话就将此处的lib随应用程序copy到/data/app/下面这个大家应该知道第三方应用的安装目录
如果没有的话,而机器有secondary ,就检查lib/<secondary-abi>/libxx.so


要将C\C++代码编译为SO文件,光有Android.mk文件还不行,还需要一个Application.mk文件。

Application.mk与Android.mk区别

Application.mk目的是描述在你的应用程序中所需要的模块(即静态库或动态库)。
Application.mk文件通常被放置在 $PROJECT/jni/Application.mk下,$PROJECT指的是您的项目。


生成多种CPU指令集的动态链接库

默认编译的是 armeabi 架构的。如果有或创建Application.mk文件,在该文件添加如下内容:

APP_ABI := armeabi armeabi-v7a mips x86

APP_ABI := all 

如图:





本文档是描述你的Android应用程序中需要的本地模块的Application.mk的语法使用。

1.  APP_PROJECT_PATH  : 这个变量是强制性的,并且会给出应用程序工程的根目录的一个绝对路径。

                                                  这是用来复制或者安装一个没有任何版本限制的JNI库,从而给APK生成工具一个详细的路径。

 

2. APP_MODULES  :   这个变量是可选的,如果没有定义,这个模块名字被定义在Android.mk文件中的 LOCAL_MODULE 中。

                                        NDK将由在Android.mk中声明的默认的模块编译,并且包含所有的子文件(makefile文), NDK会自动计算模块的依赖。

                                        如果APP_MODULES定义了,它必须是一个空格分隔的模块列表

                                        ( 注意:NDK在R4开始改变了这个变量的行为,在此之前: 在Application.mk中,该变量是强制的必须明确列出所有需要的模块)

 

 3. APP_OPTIM :   这个变量是可选的,用来定义“release”或"debug"。在编译您的应用程序模块的时候,可以用来改变优先级。
                                “release”模式是默认的,并且会生成高度优化的二进制代码。

                                  "debug"模式生成的是未优化的二进制代码,但可以检测出很多的BUG,可以用于调试。

                                  注意:如果你的应用程序是可调试的(即,如果你的清单文件在它的<application>标签中把android:debuggable属性设为true),

                                             默认将是debug而非release。把APP_OPTIM设置为release可以覆写它。

                                  注意:可以调试release和debug版二进制,但release版构建倾向于在调试会话中提供较少信息:一些变量被优化并且不能被检测,

                                              代码重新排序可能致使代码步进变得困难,堆栈跟踪可能不可靠,等等。

 

4. APP_CFLAGS : 一个C编译器开关集合,在编译任意模块的任意C或C++源代码时传递。

                                   它可以用于改变一个给定的应用程序需要依赖的模块的构建,而不是修改它自身的Android.mk文件

 

 

5. APP_BUILD_SCRIPT : 默认,NDK构建系统将在 $(APP_PROJECT_PATH)/jni 下寻找一个名为 Android.mk 的文件。即,对于这个文件

                                                 $(APP_PROJECT_PATH)/jni/Android.mk

                                                 如果你想重载这个行为,你可以定义APP_BUILD_SCRIPT指向一个不同的构建脚本。

                                                 一个非绝对路径将总是被解析为相对于NDK顶级目录的路径。

 

 

6. APP_ABI : 默认情况下,NDK的编译系统根据 "armeabi" ABI生成机器代码。可以使用APP_ABI 来选择一个不同的ABI。

                          比如:为了在ARMv7的设备上支持硬件FPU指令。可以使用  APP_ABI := armeabi-v7a

                                      或者为了支持IA-32指令集,可以使用      APP_ABI := x86

                                      或者为了同时支持这三种,可以使用       APP_ABI := armeabi armeabi-v7a x86

 

 

 

7. APP_STL :默认,NDK构建系统提供由Android系统给出的最小C++运行时库(/system/lib/libstdc++.so)的C++头文件。
                         然而,NDK带有另一个C++实现,你可以在你自己的应用程序中使用或链接它。

                        定义APP_STL以选择它们其中的一个:  APP_STL := stlport_static       -->     static STLport library
                                                                                           APP_STL := stlport_shared    -->     shared STLport library
                                                                                           APP_STL := system               -->      default C++ runtime library




以上资料源自互联网,经过综合整理而成。


0 0
原创粉丝点击