NDK 的基础概念

ndk-build

ndk-build 脚本用于在 NDK 中心启动构建脚本。这些脚本:

* 自动探测您的开发系统和应用项目文件以确定要构建的内容。
* 生成二进制文件。
* 将二进制文件复制到应用的项目路径。

原生共享库:NDK 从原生源代码构建这些库或 .so 文件。
原生静态库:NDK 也可构建静态库或 .a 文件,您可以关联到其他库。
Java 原生接口 (JNI):JNI 是 Java 和 C++ 组件用以互相沟通的接口。 本指南假设您具备 JNI 知识;其相关信息请查阅 Java原生接口规范
应用二进制界面 (ABI):ABI 可以非常精确地定义应用的机器代码在运行时如何与系统交互。 NDK 根据这些定义构建 .so 文件。 不同的 ABI 对应不同的架构:NDK 包含对 ARMEABI(默认)、MIPS 和 x86 的 ABI 支持。

构建项目

Android.mk

About

Android.mk 文件位于项目 jni/ 目录的子目录中,用于向构建系统描述源文件和共享库。 它实际上是构建系统解析一次或多次的微小 GNU makefile 片段。 Android.mk 文件用于定义 Application.mk、构建系统和环境变量所未定义的项目范围设置。 它还可替换特定模块的项目范围设置。

Android.mk 的语法用于将源文件分组为模块。 模块是静态库、共享库或独立可执行文件。 可在每个 Android.mk 文件中定义一个或多个模块,也可在多个模块中使用同一个源文件。 构建系统只会将共享库放入应用软件包。 此外,静态库可生成共享库。

变量和宏

构建系统提供许多可用于 Android.mk 文件中的变量。其中许多变量已预先赋值。 另一些变量由您赋值。

除了这些变量之外,您还可以定义自己的任意变量。在定义变量时请注意,NDK 构建系统会预留以下变量名称:

* 以 LOCAL_ 开头的名称,例如 LOCAL_MODULE。
* 以 PRIVATE_、NDK_ 或 APP 开头的名称。构建系统在内部使用这些变量。
* 小写名称,例如 my-dir。构建系统也是在内部使用这些变量。
* 如果为了方便而需要在 Android.mk 文件中定义自己的变量,建议在名称前附加 MY_。

BUILD_SHARED_LIBRARY
编译目标共享库.请注意,使用此脚本要求您至少已为 LOCAL_MODULE 和 LOCAL_SRC_FILES 赋值

BUILD_STATIC_LIBRARY
用于构建静态库的 BUILD_SHARED_LIBRARY 的变体。构建系统不会将静态库复制到您的项目/软件包,但可能使用它们构建共享库,LOCAL_STATIC_LIBRARIESLOCAL_WHOLE_STATIC_LIBRARIES

PREBUILT_SHARED_LIBRARY
指向用于指定预建共享库的构建脚本。与 BUILD_SHARED_LIBRARY 和 BUILD_STATIC_LIBRARY 的情况不同,这里的 LOCAL_SRC_FILES 值不能是源文件, 而必须是指向预建共享库的单一路径,例如 foo/libfoo.so。 使用此变量的语法为:

1
include $(PREBUILT_SHARED_LIBRARY)

也可使用 LOCAL_PREBUILTS 变量引用另一个模块中的预建库。

PREBUILT_STATIC_LIBRARY
与 PREBUILT_SHARED_LIBRARY 相同,但用于预构建的静态库。

TARGET_ARCH
Android 开放源代码项目所指定的目标 CPU 架构的名称。

TARGET_PLATFORM
作为构建系统目标的 Android API 级别号。

TARGET_ARCH_ABI
当构建系统解析此 Android.mk 文件时,此变量将 CPU 和架构的名称存储到目标。

模块描述变量

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
LOCAL_PATH := $(call my-dir)
LOCAL_MODULE := "foo"
LOCAL_SRC_FILES
LOCAL_CPP_EXTENSION := .cxx .cpp .cc \\使用此可选变量为 C++ 源文件指明 .cpp 以外的文件扩展名。
LOCAL_CPP_FEATURES \\可以使用此可选变量指明您的代码依赖于特定 C++ 功能。
LOCAL_C_INCLUDES \\使用此可选变量指定相对于 NDK root 目录的路径列表,以便在编译所有源文件(C、C++ 和 Assembly)时添加到 include 搜索路径。
LOCAL_CFLAGS \\此可选变量为构建系统设置在构建 C 和 C++ 源文件时要传递的编译器标志。
LOCAL_STATIC_LIBRARIES \\此变量用于存储当前模块依赖的静态库模块列表。
LOCAL_SHARED_LIBRARIES \\此变量是此模块在运行时依赖的共享库模块列表。 此信息在链接时需要,并且会在生成的文件中嵌入相应的信息。
LOCAL_WHOLE_STATIC_LIBRARIES \\此变量是 LOCAL_STATIC_LIBRARIES 的变体,表示链接器应将相关的库模块视为整个存档。
LOCAL_LDLIBS \\此变量包含在构建共享库或可执行文件时要使用的其他链接器标志列表。 它可让您使用 -l 前缀传递特定系统库的名称。
LOCAL_LDFLAGS \\构建共享库或可执行文件时供构建系统使用的其他链接器标志列表。
LOCAL_ALLOW_UNDEFINED_SYMBOLS \\若构建系统在尝试构建共享库时遇到未定义的引用,将会引发“未定义的符号”错误。 此错误可帮助您捕获源代码中的缺陷。
LOCAL_ARM_MODE \\
LOCAL_ARM_NEON \\
LOCAL_DISABLE_NO_EXECUTE \\

NDK 提供的函数宏

1
2
3
4
5
6
my-dir
all-subdir-makefiles
this-makefile
parent-makefile
grand-parent-makefile
import-module

Application.mk

About

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

变量

  • APP_PROJECT_PATH

    此变量用于存储应用项目根目录的绝对路径。

  • APP_OPTIM

    此可选变量定义为 release 或 debug。在构建应用的模块时可使用它来更改优化级别。

  • APP_CFLAGS

    此变量用于存储构建系统在为任何模块编译任何 C 或 C++ 源代码时传递到编译器的一组 C 编译器标志。

  • APP_CPPFLAGS

    此变量包含构建系统在仅构建 C++ 源文件时传递到编译器的一组 C++ 编译器标志。

  • APP_LDFLAGS

    构建系统在链接应用时传递的一组链接器标志。

  • APP_BUILD_SCRIPT

    NDK 构建系统在 jni/ 下查找名称为 Android.mk 的文件。如果要改写此行为,可以定义 APP_BUILD_SCRIPT 指向替代构建脚本。

  • APP_ABI

    NDK 构建系统为 armeabi ABI 生成机器代码。

ndk-build

ndk-build 文件是 Android NDK r4 中引入的一个 shell 脚本。其用途是调用正确的 NDK 构建脚本

CMake

Android Studio 2.2 之后增加了 Cmake工具支持,

独立工具链

Android NDK 原生 API