Application.mk

本文档介绍 ndk-build 所使用的 Application.mk 构建文件。

建议您先阅读概念Android.mk 页面,再阅读本页。 这样有助于您最深入地了解本页的内容。

概览

Application.mk 文件实际上是微型 GNU Makefile 片段,用于定义要编译的多个变量。 该文件通常位于 $PROJECT/jni/下,其中 $PROJECT 指向应用的项目目录。 另一种方式是将其放在顶级 $NDK/apps/ 目录的子目录下。 例如:

$NDK/apps/<myapp>/Application.mk

这里的 <myapp> 是用于向 NDK 构建系统描述应用的简称。 它不会实际进入生成的共享库或最终软件包。

变量

APP_PROJECT_PATH

此变量用于存储应用项目根目录的绝对路径。 构建系统使用此信息将生成的 JNI 共享库的简缩版放入 APK 生成工具已知的特定位置。

如果您将 Application.mk 文件放在 $NDK/apps/<myapp>/ 下,则必须定义此变量。 如果将其放在 $PROJECT/jni/ 下,则此变量可选。

APP_MODULES

如果定义此变量,变量会指示 ndk-build 仅构建相应模块及其依赖的模块。 列出模块名称时必须用空格分隔,与其在 Android.mk 文件 LOCAL_MODULE 定义中的显示方式一样。

如果未定义此变量,ndk-build 会查找所有可安装的顶级模块的列表,即 Android.mk 文件及其直接包括的任何文件所列的模块。 但是,导入的模块不是顶级模块。

可安装的模块是共享库或可执行文件,后者会在 libs/$ABI/ 中生成一个文件。

如果未定义此变量,而且项目中没有可安装的顶级模块,ndk-build 就会改为构建所有顶级静态库及其依赖项。 这些库会放在 obj/obj-debug/ 下的常用位置。

APP_OPTIM

请将这个可选变量定义为 releasedebug。 使用此变量可以在构建应用的模块时变更优化级别。

发布模式为默认模式,可以生成高度优化的二进制文件。 调试模式会生成未经优化的二进制文件,如此更容易调试。

请注意,您可以调试发布或调试二进制文件。 但是,发布二进制文件在调试时提供的信息较少。 例如,构建系统会优化掉一些变量,导致您无法对其进行检查。 此外,代码重新排序可能增大单步调试代码的难度;堆栈轨迹可能不可靠。

在应用清单的 <application> 标记中声明 android:debuggable 将导致 此变量默认为 debug 而非 release。 将 APP_OPTIM 设置为 release 可替换此默认值。

APP_CFLAGS

此变量用于存储一组 C 编译器标记,供构建系统在为任何模块编译任何 C 或 C++ 源代码时传递到编译器。 使用此变量可以根据需要给定模块的应用更改该模块的版本号,而无需修改 Android.mk 文件本身。 使用 APP_CPPFLAGS 只能为 C++ 指定标记。

这些标记中的所有路径都应相对于顶级 NDK 目录。 例如,如果您有以下设置:

sources/foo/Android.mk
sources/bar/Android.mk

要在 foo/Android.mk 中指定您在编译时要添加指向 bar 源文件的路径,应使用:

APP_CFLAGS += -Isources/bar

或者:

APP_CFLAGS += -I$(LOCAL_PATH)/../bar

-I../bar 无效,因为它相当于 -I$NDK_ROOT/../bar

APP_CPPFLAGS

此变量包含一组 C++ 编译器标记,仅供构建系统构建 C++ 源文件时传递到编译器。 使用 APP_CFLAGS 可以为 C 和 C++ 指定标记。

APP_LDFLAGS

在链接应用时,构建系统传递的一组链接程序标记。 仅当构建系统构建共享库和可执行文件时,此变量才相关。 当构建系统构建静态库时,它会忽略这些标记。

APP_BUILD_SCRIPT

默认情况下,NDK 构建系统在 jni/ 下查找名为 Android.mk 的文件。

如果您要替换此行为,可以将 APP_BUILD_SCRIPT 定义为指向替代构建脚本。 构建系统始终将非绝对路径解释为相对于 NDK 的顶级目录。

APP_ABI

默认情况下,NDK 构建系统会为所有非弃用 ABI 生成机器代码。 您可使用 APP_ABI 设置为特定的 ABI 生成机器代码。 表 1 显示不同指令集的 APP_ABI 设置。

表 1. 不同指令集的 APP_ABI 设置。

指令集
基于 ARMv7 的设备上的硬件 FPU 指令 APP_ABI := armeabi-v7a
ARMv8 AArch64 APP_ABI := arm64-v8a
IA-32 APP_ABI := x86
Intel64 APP_ABI := x86_64
所有支持的指令集 APP_ABI := all

注:all 从 NDKr7 开始可用。

您也可以通过在同一行上指定值并以空格分隔来指定多个值。 例如:

APP_ABI := armeabi-v7a arm64-v8a x86

注:如果您使用 Gradle 的 externalNativeBuild 指令将 ndk-build 项目集成到 Gradle 项目中,则会忽略 Application.mk 文件中的 APP_ABI 设置。 在 Gradle 脚本中,您可使用 abiFilters 块或者 splits 块中的 abi 块(如果您使用“多个 APK”)来配置要构建的 ABI。

如需了解所有支持的 ABI 列表及其用法和限制的详细信息,请参阅 ABI 管理

APP_PLATFORM

此变量包含您想支持的最低版本的 Android 平台。 例如,android-15 值指定您的库使用在低于 Android 4.0.3(API 级别 15)的版本中不可用的 API,而且不能在运行低版本平台的设备上使用。 如需平台名称和对应 Android 系统映像的完整列表,请参阅 Android NDK 原生 API

请勿直接更改此标记,而应设置您模块级 build.gradle 文件defaultConfigproductFlavors 块的 minSdkVersion 属性。 这样就能确保只有安装在 Android 版本足够高的设备上的应用才能使用您的库。 ndk-build 工具链使用以下逻辑,根据您所构建的 ABI 以及您指定的 minSdkVersion 来为您的库选择最低版本的平台:

  1. 如果现有 ABI 平台版本等于 minSdkVersion,则 ndk-build 会使用该版本。
  2. 否则,如果现有 ABI 平台版本低于 minSdkVersion,则 ndk-build 会使用其中版本最高的平台。 这种选择较为合理,因为通常情况下,平台版本缺失意味着自上一个可用版本以来,原生平台 API 未作任何改变。
  3. 否则,ndk-build 会使用下一个高于 minSdkVersion 的可用平台版本。

APP_STL

NDK 构建系统默认为 STL`system`。 其他选项包括 `c++_shared`、`c++_static` 和 `none`。 请参阅 NDK 运行时和功能

APP_SHORT_COMMANDS

相当于 Application.mk 中的 LOCAL_SHORT_COMMANDS,适用于整个项目。 如需了解详细信息,请参阅 Android.mk 中有关此变量的文档。

APP_THIN_ARCHIVE

Android.mk 文件中,为此项目中的所有静态库模块设置 LOCAL_THIN_ARCHIVE 默认值。 如需了解详细信息,请参阅 Android.mk 中有关 LOCAL_THIN_ARCHIVE 的文档。