在JNI介绍(一)中,jni目录下新增了两个文件Android.mk和Application.mk,以及对app下的build.gradle都进行了修改。
此篇介绍下这几个文件的内容。
1. Android.mk
Android.mk 文件位于项目 jni/ 目录的子目录中,用于向编译系统描述源文件和共享库。
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := myjni
LOCAL_SRC_FILES := toolsfromc.c toasttools.c
include $(BUILD_SHARED_LIBRARY)
Google官方的说明:https://developer.android.google.cn/ndk/guides/android_mk
1.1 基础知识
1.1.1 Android.mk 文件必须先定义 LOCAL_PATH 变量:
LOCAL_PATH := $(call my-dir)
此变量表示源文件在开发树中的位置。在这行代码中,编译系统提供的宏函数 my-dir 将返回当前目录(Android.mk 文件本身所在的目录)的路径。
1.1.2 声明 CLEAR_VARS 变量,其值由编译系统提供:
include $(CLEAR_VARS)
CLEAR_VARS 变量指向一个特殊的 GNU Makefile,后者会清除许多 LOCAL_XXX 变量,例如 LOCAL_MODULE、LOCAL_SRC_FILES 和 LOCAL_STATIC_LIBRARIES。请注意,GNU Makefile 不会清除 LOCAL_PATH。此变量必须保留其值,因为系统在单一 GNU Make 执行环境(其中的所有变量都是全局变量)中解析所有编译控制文件。在描述每个模块之前,必须声明(重新声明)此变量。
1.1.3 LOCAL_MODULE:变量存储您要编译的模块的名称。
LOCAL_MODULE := myjni
每个模块名称必须唯一,且不含任何空格。编译系统在生成最终共享库文件时,会对您分配给 LOCAL_MODULE 的名称自动添加正确的前缀和后缀。例如,会生成名为 libmyjni.so 的库。
注意:如果模块名称的开头已经是 lib
,则编译系统不会附加额外的 lib
前缀;而是按原样采用模块名称,并添加 .so
扩展名。因此,比如原来名为 libfoo.c
的源文件仍会生成名为 libfoo.so
的共享对象文件。此行为是为了支持 Android 平台源文件根据 Android.mk
文件生成的库;所有这些库的名称都以 lib
开头。
1.1.4 LOCAL_SRC_FILES
变量必须包含要编译到模块中的 C 和/或 C++ 源文件列表,以空格分隔多个文件
1.1.5 include $(BUILD_SHARED_LIBRARY)
帮助系统将所有内容连接到一起。BUILD_SHARED_LIBRARY 变量指向一个 GNU Makefile 脚本,该脚本会收集您自最近 include 以来在 LOCAL_XXX 变量中定义的所有信息。此脚本确定要编译的内容以及编译方式。BUILD_SHARED_LIBRARY 共享库变量会导致编译系统生成扩展名为 .so 的库文件。
2.Application.mk
Google的官方说明:https://developer.android.google.cn/ndk/guides/application_mk
Application.mk 指定了 ndk-build 的项目范围设置。默认情况下,它位于应用项目目录中的 jni/Application.mk 下。
APP_MODULES := myjni
APP_ABI := all
2.1 APP_ABI
默认情况下,NDK 编译系统会为所有非弃用 ABI 生成代码。您可以使用 APP_ABI 设置为特定 ABI 生成代码。表 1 显示了不同指令集的 APP_ABI 设置。
表 1. 不同指令集的 APP_ABI
设置。
指令集 | 值 |
---|---|
32 位 ARMv7 | APP_ABI := armeabi-v7a |
64 位 ARMv8 (AArch64) | APP_ABI := arm64-v8a |
x86 | APP_ABI := x86 |
x86-64 | APP_ABI := x86_64 |
所有支持的 ABI(默认) | APP_ABI := all |
也可以指定多个值,方法是将它们放在同一行上,中间用空格分隔。例如:
APP_ABI := armeabi-v7a arm64-v8a x86
2.2 APP_MODULES
要编译的模块的显式列表。此列表的元素是模块在 Android.mk 文件的 LOCAL_MODULE
中显示的名称。默认情况下,ndk-build 将编译所有共享库、可执行文件及其依赖项。