# Android_NDK **Repository Path**: owant/Android_NDK ## Basic Information - **Project Name**: Android_NDK - **Description**: 经过精简的Android_NDK开发工具集,经过精简,去除了不用的一些内容,适用于VS Code和独立开发工具,而且其内的头文件经过部分中文注释. - **Primary Language**: C++ - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 2 - **Created**: 2022-03-27 - **Last Updated**: 2022-05-24 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README Android NDK =========== ## 简介 本目录下的是安卓ndk的一个副本,主要用具构建安卓native构件. * 构建ndk的三种方式 1. 使用[ndk-build](https://developer.android.google.cn/ndk/guides/ndk-build)工具链进行构建 2. 使用[cmake](https://developer.android.google.cn/ndk/guides/cmake)进行构建 3. 使用[原始命令调用Clang](https://developer.android.google.cn/ndk/guides/other_build_systems)进行构建 4. 使用[独立工具链](https://developer.android.google.cn/ndk/guides/standalone_toolchain)进行构建 ## 结构 文件|作用 |:-|:-| build|构建脚本的储存目录 meta|配置文件 platforms|不同Android版本下的链接库 prebuilt|预构建文件,主要用于远程调试 python-packages|python文件夹,python构建的工具集 shader-tools|影子工具(没弄懂) simpleperf|cpu性能分析工具 source|NDK自带的一些源代码库 sysroot|所有头文件的位置 toolchains|针对不同的平台的不同的构建工具链 wrap.sh|打包的脚本 ndk-build.cmd|构建工具 ndk-gdb.cmd|调试工具 ndk-stack.cmd| 堆栈追踪工具 ndk-which.cmd|在调试时选择ABI和调试工具(*弃用*) source.properties|ndk版本信息 ## 目录详解 1. * sysroot * 在ndk的根目录中应该包含一个sysroot目录,但是 在toolchains文件中包含真实的构建工具链, 在llvm中包含sysroot目录,其中包含真实的sysroot 目录,在本目录中的sysroot目录只是llvm目录中的sysroot 的一个副本. 2. * prebuilt * 预构建的调试器,在其中有对应不同Android目标ABI的远程调试 工具,和本地调试工具. 3. * build * 主要的构建脚本所在文件夹,包含构建主要的的规则.类似`CLEAR_VARS`脚本都在其中. 4. * meta * 对于一些数据的配置,例如支持的ABI,支持的平台,一些系统库的版本. 5. * platforms * 针对不同的Android版本所对应的链接库,其中每个不同的ABI系列下有不同的对应库文件.在toolchain的llvm文件夹的sysroot目录中包含lib目录,其中是以不同的CPU架构来设置文件夹的,其中每个文件中又包含不同的Android版本库,二者是对应的,但是在链接时需要使用platforms下的系统库,所以这个文件夹不能像假的sysroot目录一样删掉.在Linux系统下,可能此目录是一个假的软连接,但在Windows目录下不是. 6. * python-packages * 使用python写成的一些工具集,包含adb,fastboot,gdbrunner三个工具集.应该都是用于ndk-gdb脚本的,暂时不做研究. 7. * shader-tools * 性能测试工具,没进行研究. 8. * simpleperf * cpu性能分析工具. 9. sources * 某些第三方库的源文件和构建目录 10. toolchains * 构建目标文件的工具链,包含llvm工具链和针对不同平台的链接器和库文件. 11. wrap.sh * 一个包装脚本,在windows下无法使用. ## 工具详解 ### 1. ndk-build.cmd 简介: 构建ndk工程的工具,是对一系列make脚本的包装 内部原理 : ``` $GNUMAKE -f \/build/core/build-local.mk \ make构建工具 -f \/build/core/build-local.mk \<参数\> ``` 命令行调用: 在构建目录下运行ndk-build脚本 ndk-build可选参数[参考网页](https://developer.android.google.cn/ndk/guides/ndk-build): |选项|含义| |:-|:-| clean|清除之前生成的所有二进制文件 V=1|显示构建命令 -B|强制执行完整构建 NDK_DEBUG=1|强制执行可调试构建 NDK_DEBUG=0|强制发布build NDK_HOST_32BIT=1|始终使用32位构建工具 NDK_APPLICATION_MK=\|使用指定的Application.mk文件 -C \ | 构建指定project目录下的项目 ndk-build构建工具需要使用: `Android.mk` 和 `Application.mk` #### `Android.mk` 构建规则脚本 [参考网页](https://developer.android.google.cn/ndk/guides/android_mk) 该脚本定义构建规则和构建目标,是构建静态库,动态库,还是构建可执行文件. 同时定义依赖项和导出项. 最基本构建模块: ```makefile LOCAL_PATH:= $(call my-dir) #设定项目目录 include $(CLEAR_VARS) #包含清除变量的系统脚本 LOCAL_MODULE := hello-jni #声明构建的模块名称 LOCAL_SRC_FILES := hello-jni.c #声明要构建的文件 include $(BUILD_SHARED_LIBRARY) #声明构建共享库文件 ``` 变量与宏: * 最好不要使用的变量名称 - 以`LOCAL_`开头的变量名称 , 例如 `LOCAL_MODULE` - 以 `PRIVATE_` , `NDK_` , `APP_`开头的名称会被构架系统使用. - 小写名称,例如`my-dir`,构建系统也会使用. * 如果要是用自定义变量,请以特定名称开头,例如`MY_ `,来避免与内部变量冲突. include变量(包含指定的构建模式): ```makefile # 使用方式: include $(VARS) ``` * `CLAER_VARS` 清除本地变量,会清除所有`LOCAL_`开头的变量. * `BUILD_EXECUTABLE` 根据`LOCAL_`变量可执行文件. * `BUILD_SHARED_LIBRARY` 根据`LOCAL_`变量构建动态库文件. * `BUILD_STATIC_LIBRARY` 根据`LOCAL_`变量构建静态库文件. * `PREBUILT_SHARED_LIBRARY` 指向用于指定预构建共享库的构建脚本。与 BUILD_SHARED_LIBRARY 和 BUILD_STATIC_LIBRARY 的情况不同,这里的 LOCAL_SRC_FILES 值不能是源文件,而必须是指向预构建共享库的单一路径,例如 foo/libfoo.so。 * `PREBUILT_STATIC_LIBRARY` 与 `PREBUILT_SHARED_LIBRARY` 相同,但用于预构建静态库。 目标信息变量: 构建系统会根据ABI的不同重新解析`Android.mk`,进行重新构建. * `TARGET_ARCH` 不同的cpu系列, arm , arm64 , x86 , x86_64 四种架构系列. * `TARGET_PLATFORM` 对应Android-API版本,例如`android-23`. * `TARGET_ARCH_ABI` 解析`Android.mk`时使用的ABI, 详情见-[ABI架构对应表]. * `TARGET_ABI` 目标Android API 级别和ABI的串联. 例如: `android-23-arm64-v8a`. ABI架构对应表 |ABI(CPU和架构)|设置名| |:-|:-| ARMv7|armeabi-v7a ARMv8 AArch64|arm64-v8a i686|x86 x86_64|x86_64 实例: ```makefile # cpu系列 ifeq ($(TARGET_ARCH),arm) # do something endif # 版本信息 ifeq ($(TARGET_PLATFORM),android-22) # do something endif #关于ABI ifeq ($(TARGET_ARCH_ABI),arm64-v8a) # do something endif # 使用目标构建 ifeq ($(TARGET_ABI) ,android-23-arm64-v8a) # do something endif ``` 模块描述变量: * `LOCAL_PATH` 定义当前路径. * `LOCAL_MODULE` 定义当前模块名称. * `LOCAL_MODULE_FILENAME` 定义生成模块的名称. * `LOCAL_SRC_FILES` 包含的源文件. * `LOCAL_CPP_EXTENSION` 使用指定的文件扩展名作为CPP文件的扩展名. * `LOCAL_CPP_FEATURES` 指定使用的c++特性.例如: -frtti -fexceptions ```makefile LOCAL_CPP_FEATURES := exceptions rtti ``` * `LOCAL_C_INCLUDES` 指定的C头文件包含目录,相对于 `NDK root`目录的路径列表. * `LOCAL_CFLAGS` 传递给C编译器的命令标识. * `LOCAL_CPPFLAGS` 传递给C++编译器的命令标识. * `LOCAL_STATIC_LIBRARIES` 指定当前模块构建时要依赖的静态库. * `LOCAL_SHARED_LIBRARIES` 指定构建当前模块所需的静态库模块. * `LOCAL_WHOLE_STATIC_LIBRARIES` 此变量是 LOCAL_STATIC_LIBRARIES 的变体,表示链接器应将相关的库模块视为完整归档。如需详细了解完整归档,请参阅有关 `--whole-archive` 标记的 [GNU Id](http://ftp.gnu.org/old-gnu/Manuals/ld-2.9.1/html_node/ld_3.html) 文档。 多个静态库之间存在循环依赖关系时,此变量十分有用。使用此变量构建共享库时,它将强制构建系统将静态库中的所有对象文件添加到最终二进制文件。但是,生成可执行文件时不会发生这种情况。 * `LOCAL_LDLIBS` 此变量列出了在构建共享库或可执行文件时使用的额外链接器标记。利用此变量,您可使用 -l 前缀传递特定系统库的名称. 例如,以下示例指示链接器生成在加载时链接到 /system/lib/libz.so 的模块: ```makefile LOCAL_LDLIBS := -lz ``` 说白了,就是链接指定的Android库. [Android NDK 原生API库](https://developer.android.google.cn/ndk/guides/stable_apis) *注意 : 该构建变量只对可执行文件和共享库有用,对于静态库无用.* * `LOCAL_LDFLAGS` 构建系统在构建共享库和可执行文件时使用的其他连接器标记。例如,在ARM/X86上使用ld.bfd连接器. ``` LOCAL_LDFLAGS += -fuse-ld=bfd ``` *静态库不适用此变量.* * `LOCAL_ALLOW_UNDEFINED_SYMBOLS` 默认情况下,如果构建系统在尝试构建共享库时遇到未定义的引用,将会抛出“未定义的符号”错误。此错误可帮助您捕获源代码中的错误。如果停用此检查,请将此变量设置为ture. *注意 : 静态库不适应此变量.* * `LOCAL_ARM_MODE` 默认情况下,构建系统会以 thumb 模式生成 ARM 目标二进制文件,其中每条指令都是 16 位宽,并与 thumb/ 目录中的 STL 库链接。将此变量定义为 arm 会强制构建系统以 32 位 arm 模式生成模块的对象文件。 ```makefile LOCAL_ARM_MODE := arm ``` * `LOCAL_ARM_NEON` 此变量仅在以 armeabi-v7a ABI 为目标时才有意义。它允许在 C 和 C++ 源文件中使用 ARM Advanced SIMD (NEON) 编译器固有特性,以及在 Assembly 文件中使用 NEON 指令。 请注意,并非所有基于 ARMv7 的 CPU 都支持 NEON 扩展指令集。因此,必须执行运行时检测,以便在运行时安全地使用此代码。如需了解详细信息,请参阅 NEON 支持和 cpufeatures 库。 此外,您也可以使用 .neon 后缀,指定构建系统仅以 NEON 支持来编译特定源文件。在以下示例中,构建系统以 Thumb 和 NEON 支持编译 foo.c,以 Thumb 支持编译 bar.c,并以 ARM 和 NEON 支持编译 zoo.c: ```makefile LOCAL_SRC_FILES = foo.c.neon bar.c zoo.c.arm.neon ``` * `LOCAL_DISABLE_FORMAT_STRING_CHECKS` 默认情况下,构建系统会在编译代码时保护格式字符串。这样的话,如果 printf 样式的函数中使用了非常量格式的字符串,就会强制引发编译器错误。此保护默认启用,但您也可通过将此变量的值设置为 true 将其停用。如果没有必要的原因,我们不建议停用。 * `LOCAL_EXPORT_CFLAGS` 此变量用于记录一组 C/C++ 编译器标记,这些标记将添加到通过 `LOCAL_STATIC_LIBRARIES` 或 `LOCAL_SHARED_LIBRARIES` 变量使用此模块的任何其他模块的 `LOCAL_CFLAGS` 定义中。 ```makefile include $(CLEAR_VARS) LOCAL_MODULE := foo LOCAL_SRC_FILES := foo/foo.c LOCAL_EXPORT_CFLAGS := -DFOO=1 include $(BUILD_STATIC_LIBRARY) include $(CLEAR_VARS) LOCAL_MODULE := bar LOCAL_SRC_FILES := bar.c LOCAL_CFLAGS := -DBAR=2 LOCAL_STATIC_LIBRARIES := foo include $(BUILD_SHARED_LIBRARY) ``` 在这里,构建系统在构建 bar.c 时会向编译器传递 -DFOO=1 和 -DBAR=2 标记。它还会在模块的 `LOCAL_CFLAGS` 前面加上导出的标记,以便您轻松进行 替换。 此外,模块之间的关系也具有传递性:如果 zoo 依赖 于 bar,而后者依赖于 foo,那么 zoo 也会继承从 foo 导出的所有标记。 最后,构建系统在执行局部构建时(即,构建要导出标 记的模块时),不使用导出的标记。因此,在以上示例 中,构建系统在构建 foo/foo.c 时不会将 -DFOO=1 传递到编译器。如需执行局部构建,请改用`LOCAL_CFLAGS`。 * `LOCAL_EXPORT_CPPFLAGS` 类似于`LOCAL_EXPORT_CFLAGS`,只是面对与CPP的. * `LOCAL_EXPORT_C_INCLUDES` 此变量与 `LOCAL_EXPORT_CFLAGS` 相同,但适用于 C include 路径。例如,当 bar.c 需要包括模块 foo 的头文件时,此变量很有用。 * `LOCAL_EXPORT_LDFLAGS` 此变量与 LOCAL_EXPORT_CFLAGS 相同,但适用于链接器标记。 * `LOCAL_EXPORT_LDLIBS` 此变量与 `LOCAL_EXPORT_CFLAGS` 相同,用于指示构建系统将特定系统库的名称传递到编译器。请在您指定的每个库名称前附加 -l。 请注意,构建系统会将导入的链接器标记附加到模块的 `LOCAL_LDLIBS` 变量值上。其原因在于 Unix 链接器的工作方式。 当模块 foo 是静态库并且具有依赖于系统库的代码时,此变量通常很有用。然后,您可以使用 `LOCAL_EXPORT_LDLIBS` 导出依赖项。 例如: ```makefile include $(CLEAR_VARS) LOCAL_MODULE := foo LOCAL_SRC_FILES := foo/foo.c LOCAL_EXPORT_LDLIBS := -llog include $(BUILD_STATIC_LIBRARY) include $(CLEAR_VARS) LOCAL_MODULE := bar LOCAL_SRC_FILES := bar.c LOCAL_STATIC_LIBRARIES := foo include $(BUILD_SHARED_LIBRARY) ``` 在此示例中,构建系统在构建 libbar.so 时,将在链接器命令的末尾指定 -llog。这样就会告知链接器,由于 libbar.so 依赖于 foo,因此它也依赖于系统日志记录库。 * `LOCAL_SHORT_COMMANDS` 当您的模块有很多源文件和/或依赖的静态或共享库时,请将此变量设置为 true。这样会强制构建系统将 @ 语法用于包含中间对象文件或链接库的归档。 此功能在 Windows 上可能很有用,在 Windows 上,命令行最多只接受 8191 个字符,这对于复杂的项目来说可能太少。它还会影响个别源文件的编译,而且将几乎所有编译器标记都放在列表文件内。 请注意,true 以外的任何值都将恢复为默认行为。您也可以在 `Application.mk` 文件中定义 `APP_SHORT_COMMANDS`,对项目中的所有模块强制实施此行为。 我们不建议默认启用此功能,因为它会减慢构建速度。 * `LOCAL_THIN_ARCHIVE` 构建静态库时,请将此变量设置为 true。这样会生成一个瘦归档,即一个库文件,其中不含对象文件,而只包含它通常包含的实际对象的文件路径。 这对于减小构建输出的大小非常有用。但缺点是,这样的库无法移至其他位置(其中的所有路径都是相对路径)。 有效值为 true、false 或空白。您可在 `Application.mk` 文件中通过 `APP_THIN_ARCHIVE` 变量来设置默认值。 *注意 : 此变量对于非静态库和预构件库无用.* * `LOCAL_FILTER_ASM` 请将此变量定义为一个 shell 命令,供构建系统用于过滤根据您为 `LOCAL_SRC_FILES` 指定的文件提取或生成的汇编文件。定义此变量会导致发生以下情况 : 1. 构建系统从任何C或者C++文件生成临时汇编文件,而不进行编译. 2. 构建系统在任何临时汇编文件以及`LOCAL_SRC_FILES`中所列任何汇编文件的`LOCAL_FILTER_ASM`中执行shell命令,因此会生成另一个临时汇编文件. 3. 构建系统将这些过滤的汇编文件编译到对象文件中. 示例: ```makefile LOCAL_SRC_FILES := foo.c bar.S LOCAL_FILTER_ASM := foo.c --1--> $OBJS_DIR/foo.S.original --2--> $OBJS_DIR/foo.S --3--> $OBJS_DIR/foo.o bar.S --2--> $OBJS_DIR/bar.S --3--> $OBJS_DIR/bar.o ``` “1”对应于编译器,“2”对应于过滤器,“3”对应于汇编程序。过滤器必须是一个独立的 shell 命令,它接受输入文件名作为第一个参数,接受输出文件名作为第二个参数。 例如: ```makefile myasmfilter $OBJS_DIR/foo.S.original $OBJS_DIR/foo.S myasmfilter bar.S $OBJS_DIR/bar.S ``` NDK提供的宏函数: * `my-dir` 这个宏返回最后包括的 `makefile` 的路径,通常是当前 `Android.mk` 的目录。`my-dir` 可用于在 `Android.mk` 文件开头定义 `LOCAL_PATH`。 例如: ```makefile LOCAL_PATH := $(call my-dir) ``` 由于 GNU Make 的工作方式,这个宏实际返回的是构建系统解析构建脚本时包含的最后一个 makefile 的路径。因此,包括其他文件后就不应调用 my-dir。 例如: ```makefile LOCAL_PATH := $(call my-dir) # ... declare one module include $(LOCAL_PATH)/foo/`Android.mk` LOCAL_PATH := $(call my-dir) # ... declare another module ``` 这里的问题在于,对 my-dir 的第二次调用将 LOCAL_PATH 定义为 $PATH/foo,而不是 $PATH,因为这是其最近的 include 所指向的位置。 在 Android.mk 文件中的任何其他内容后指定额外的 include 可避免此问题。 例如: ```makefile LOCAL_PATH := $(call my-dir) # ... declare one module LOCAL_PATH := $(call my-dir) # ... declare another module # extra includes at the end of the Android.mk file include $(LOCAL_PATH)/foo/Android.mk ``` 如果以这种方式构造文件不可行,请将第一个 my-dir 调用的值保存到另一个变量中。 例如: ```makefile MY_LOCAL_PATH := $(call my-dir) LOCAL_PATH := $(MY_LOCAL_PATH) # ... declare one module include $(LOCAL_PATH)/foo/`Android.mk` LOCAL_PATH := $(MY_LOCAL_PATH) # ... declare another module ``` * `all-subdir-makefiles` 返回位于当前 my-dir 路径所有子目录中的 Android.mk 文件列表。 利用此函数,您可以为构建系统提供深度嵌套的源目录层次结构。默认情况下,NDK 只在 Android.mk 文件所在的目录中查找文件。 * `this-makefile` 返回当前 makefile(构建系统从中调用函数)的路径。 * `parent-makefile` 返回包含树中父 makefile 的路径(包含当前 makefile 的 makefile 的路径)。 * `grand-parent-makefile` 返回包含树中祖父 makefile 的路径(包含当前父 makefile 的 makefile 的路径)。 * `import-module` 此函数用于按模块名称来查找和包含模块的 Android.mk 文件。典型的示例如下所示: ```makefile $(call import-module,) ``` 在此示例中,构建系统在 NDK_MODULE_PATH 环境变量所引用的目录列表中查找具有 标记的模块,并且自动包括其 Android.mk 文件。 #### `Application.mk`构建配置脚本 概览: `Application.mk` 指定 ndk-build 的项目级设置。默认情况下,它位于应用项目目录中的 jni/Application.mk 下。 *注意*:*其中许多参数也具有模块等效项。例如,APP_CFLAGS 对应于 LOCAL_CFLAGS。无论何种情况下,特定于模块的选项都将优先于应用级选项。对于标记,两者都使用,但特定于模块的标记将后出现在命令行中,因此它们可能会替换项目级设置。* * `APP_ABI` 默认情况下,NDK 构建系统会为所有非弃用 ABI 生成代码。您可以使用 APP_ABI 设置为特定 ABI 生成代码。下表显示了不同指令集的 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 [详细ABI参见这里](https://developer.android.google.cn/ndk/guides/abis) 您也可以指定多个值,方法是将它们放在同一行上,中间用空格分隔。例如: ```makefile APP_ABI := armeabi-v7a arm64-v8a x86 ``` * `APP_ASFLAGS` 要传递给项目中每个汇编源文件(.s 和 .S 文件)的编译器的标记。 *注意:`ASFLAGS` 与 `ASMFLAGS` 不同。后者专用于 YASM 源文件(请参阅关于 `APP_ASMFLAGS` 的部分)。* * `APP_ASMFLAGS` 对于所有 YASM 源文件(.asm,仅限 x86/x86_64),要传递给 YASM 的标记。 * `APP_BUILD_SCRIPT` 默认情况下,`ndk-build` 假定 `Android.mk` 文件位于项目根目录的相对路径 `jni/Android.mk` 中。 如需从其他位置加载 `Android.mk` 文件,请将 `APP_BUILD_SCRIPT` 设置为 `Android.mk` 文件的绝对路径。 * `APP_CFLAGS` 要为项目中的所有 C/C++ 编译传递的标记。 *注意:Include 路径应使用 `LOCAL_C_INCLUDES` 而不是显式 -I 标记。* * `APP_CLANG_TIDY` 若要为项目中的所有模块启用 clang-tidy,请将此标记设置为“True”。默认处于停用状态。 * `APP_CLANG_TIDY_FLAGS` 要为项目中的所有 clang-tidy 执行传递的标记。 * `APP_CONLYFLAGS` 要为项目中的所有 C 编译传递的标记。这些标记不会用于 C++ 代码。 * `APP_CPPFLAGS` 要为项目中的所有 C++ 编译传递的标记。这些标记不会用于 C 代码。 * `APP_CXXFLAGS` *注意:`APP_CPPFLAGS` 应优先于 `APP_CXXFLAGS`。* 与 `APP_CPPFLAGS` 相同,但在编译命令中将出现在 `APP_CPPFLAGS` 之后。例如: ```makefile APP_CPPFLAGS := -DFOO APP_CXXFLAGS := -DBAR ``` 以上配置将导致编译命令类似于 clang++ -DFOO -DBAR,而不是 clang++ -DBAR -DFOO。 * `APP_DEBUG` 若要构建可调试的应用,请将此标记设置为`True`。 * `APP_LDFLAGS` 关联可执行文件和共享库时要传递的标记。 *注意:这些标记对静态库没有影响。不会关联静态库。* * `APP_MANIFEST` `AndroidManifest.xml` 文件的绝对路径。 默认情况下将使用 `$(APP_PROJECT_PATH)/AndroidManifest.xml)`(如果存在)。 *注意:使用 externalNativeBuild 时,Gradle 不会设置此值。* * `APP_MODULES` 要构建的模块的显式列表。此列表的元素是模块在 Android.mk 文件的 `LOCAL_MODULE` 中显示的名称。 默认情况下,ndk-build 将构建所有共享库、可执行文件及其依赖项。仅当项目使用静态库、项目仅包含静态库或者在 `APP_MODULES` 中指定了静态库时,才会构建静态库。 *注意:将不会构建导入的模块(在使用 $(call import-module) 导入的构建脚本中定义的模块),除非要在 `APP_MODULES` 中构建或列出的模块依赖导入的模块。* * `APP_OPTIM` 将此可选变量定义为 `release` 或 `debug`。默认情况下,将构建发布二进制文件。 发布模式会启用优化,并可能生成无法与调试程序一起使用的二进制文件。调试模式会停用优化,以便可以使用调试程序。 请注意,您可以调试发布二进制文件或调试二进制文件。但是,发布二进制文件在调试期间提供的信息较少。例如,变量可能会被优化掉,导致无法检查代码。此外,代码重新排序会使单步调试代码变得更加困难;堆栈轨迹更可能不可靠。 在应用清单的 \ 标记中声明 `android:debuggable` 将导致此变量默认为 `debug`,而不是 `release`。通过将 `APP_OPTIM` 设置为 `release` 可替换此默认值。 *意:使用 externalNativeBuild 进行构建时,Android Studio 将根据您的构建风格适当地设置此标记。* * `APP_PLATFORM` `APP_PLATFORM` 会声明构建此应用所面向的 `Android API` 级别,并对应于应用的 minSdkVersion。 如果未指定,ndk-build 将以 NDK 支持的最低 API 级别为目标。最新 NDK 支持的最低 API 级别总是足够低,可以支持几乎所有有效设备。 **警告:将 `APP_PLATFORM` 设置为高于应用的 minSdkVersion 可能会生成一个无法在旧设备上运行的应用。在大多数情况下,库将无法加载,因为它们引用了在旧设备上不可用的符号。** 例如,值 android-16 指定库使用在 Android 4.1(API 级别 16)以前的版本中不可用的 API,并且无法在运行较低平台版本的设备上使用。如需查看平台名称和相应 Android 系统映像的完整列表,请参阅 Android NDK 原生 API。 使用 Gradle 和 externalNativeBuild 时,不应直接设置此参数。而应在模块级别 build.gradle 文件的 defaultConfig 或 productFlavors 块中设置 minSdkVersion 属性。这样就能确保只有在运行足够高 Android 版本的设备上安装的应用才能使用您的库。 请注意,NDK 不包含 Android 每个 API 级别的库,省略了不包含新的原生 API 的版本以节省 NDK 中的空间。ndk-build 按以下优先级降序使用 API: 1. 匹配 `APP_PLATFORM` 的平台版本。 2. 低于 `APP_PLATFORM` 的下一个可用 API 级别。例如,`APP_PLATFORM` 为 android-20 时,将使用 android-19,因为 android-20 中没有新的原生 API。 3. NDK 支持的最低 API 级别。 * `APP_PROJECT_PATH` 项目根目录的绝对路径。 * `APP_SHORT_COMMANDS` `LOCAL_SHORT_COMMANDS` 的项目级等效项。如需了解详情,请参阅 `Android.mk` 中有关 `LOCAL_SHORT_COMMANDS` 的文档。 * `APP_STL` 用于此应用的 C++ 标准库。 默认情况下使用 `system STL`。其他选项包括 `c++_shared`、`c++_static` 和 `none`。请参阅 [NDK 运行时和功能](https://developer.android.google.cn/ndk/guides/cpp-support#runtimes)。 * `APP_STRIP_MODE` 要为此应用中的模块传递给 `strip` 的参数。默认为 `--strip-unneeded`。若要避免剥离模块中的所有二进制文件,请将其设置为 `none`。如需了解其他剥离模式,请参阅[剥离文档](https://sourceware.org/binutils/docs/binutils/strip.html)。 * `APP_THIN_ARCHIVE` 若要为项目中的所有静态库使用瘦归档,请将此变量设置为`“True”`。如需了解详情,请参阅 `Android.mk` 中有关 [`LOCAL_THIN_ARCHIVE`](LOCAL_THINARCHIVE) 的文档。 * `APP_WRAP_SH` 要包含在此应用中的 wrap.sh 文件的路径。 每个 ABI 都存在此变量的变体,ABI 通用变体也是如此: - `APP_WRAP_SH` - `APP_WRAP_SH_armeabi-v7a` - `APP_WRAP_SH_arm64-v8a` - `APP_WRAP_SH_x86` - `APP_WRAP_SH_x86_64` *注意:`APP_WRAP_SH_` 可能无法与 `APP_WRAP_SH` 结合使用。如果有任何 ABI 使用特定于 ABI 的 wrap.sh,所有 ABI 都必须使用该 wrap.sh。* ## Android 版本号 版本号 | API版本号 |:-|:-| 2.3.3 - 2.3.7 | 10 4.0.3 - 4.0.4 | 15 4.1.x | 16 4.2.x | 17 4.3 | 18 4.4 | 19 5.0 | 21 5.1 | 22 6.0 | 23 7.0 | 24 7.1 | 25 8.0 | 26 8.1 | 27 9 | 28 10 | 29 * 这个版本的NDK只支持API 16以上的 **注意** ndk-witch.cmd是适用于GCC系列的调试选择工具,对于LLVM不适用,而现在ndk又使用LLVM做编译器,弃用了GCC,那么这个调试工具之应用于GCC所构建的项目之中,因此,其也要被废弃。 ## 精简内容 * 删除了大量的NOCTICE文件. * 删除了Change文件. * 删除了软连接sysroot文件夹. * 删除ndk-switch脚本. ## 免责声明 本副本只是一个个人研究的版本, 如若用于商业用途,请使用Android官方发布的正式版本. 请勿将本版本ndk用于商业用途. ## 文档 NDK 文档, 教程, 还有API的信息可以访问 [我们的网站](https://developer.android.google.cn/ndk/index.html). NDK 代码示例可以访问 [GitHub](https://github.com/googlesamples/android-ndk). 关于Android Studio的信息可以访问 [Android Studio 网页](https://developer.android.google.cn/studio/index.html). ## 发现GUG 只要能运行,谁在乎??? NDK bugs should be filed on [GitHub](https://github.com/android-ndk/ndk/issues/new). Android Studio and Gradle bugs should be filed in the [Android Studio Bug Tracker](http://b.android.com). For the fastest response, make sure you follow their guide on [Filing Bugs](http://tools.android.com/filing-bugs).