本目录下的是安卓ndk的一个副本,主要用具构建安卓native构件.
文件 | 作用 |
---|---|
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版本信息 |
CLEAR_VARS
脚本都在其中.sources
toolchains
wrap.sh
简介: 构建ndk工程的工具,是对一系列make脚本的包装
内部原理 :
$GNUMAKE -f \<ndk\>/build/core/build-local.mk \<parameters\>
make构建工具 -f \<ndk目录\>/build/core/build-local.mk \<参数\>
命令行调用: 在构建目录下运行ndk-build脚本
ndk-build可选参数参考网页:
选项 | 含义 |
---|---|
clean | 清除之前生成的所有二进制文件 |
V=1 | 显示构建命令 |
-B | 强制执行完整构建 |
NDK_DEBUG=1 | 强制执行可调试构建 |
NDK_DEBUG=0 | 强制发布build |
NDK_HOST_32BIT=1 | 始终使用32位构建工具 |
NDK_APPLICATION_MK=<file> | 使用指定的Application.mk文件 |
-C <project> | 构建指定project目录下的项目 |
ndk-build构建工具需要使用: Android.mk
和 Application.mk
Android.mk
构建规则脚本参考网页
该脚本定义构建规则和构建目标,是构建静态库,动态库,还是构建可执行文件.
同时定义依赖项和导出项.
最基本构建模块:
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变量(包含指定的构建模式):
# 使用方式:
include $(VARS)
CLAER_VARS
LOCAL_
开头的变量.BUILD_EXECUTABLE
LOCAL_
变量可执行文件.BUILD_SHARED_LIBRARY
LOCAL_
变量构建动态库文件.BUILD_STATIC_LIBRARY
LOCAL_
变量构建静态库文件.PREBUILT_SHARED_LIBRARY
PREBUILT_STATIC_LIBRARY
PREBUILT_SHARED_LIBRARY
相同,但用于预构建静态库。目标信息变量:
构建系统会根据ABI的不同重新解析Android.mk
,进行重新构建.
TARGET_ARCH
TARGET_PLATFORM
android-23
.TARGET_ARCH_ABI
Android.mk
时使用的ABI,TARGET_ABI
android-23-arm64-v8a
.ABI架构对应表
ABI(CPU和架构) | 设置名 |
---|---|
ARMv7 | armeabi-v7a |
ARMv8 AArch64 | arm64-v8a |
i686 | x86 |
x86_64 | x86_64 |
实例:
# 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
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 文档。
多个静态库之间存在循环依赖关系时,此变量十分有用。使用此变量构建共享库时,它将强制构建系统将静态库中的所有对象文件添加到最终二进制文件。但是,生成可执行文件时不会发生这种情况。
LOCAL_LDLIBS
此变量列出了在构建共享库或可执行文件时使用的额外链接器标记。利用此变量,您可使用 -l 前缀传递特定系统库的名称.
例如,以下示例指示链接器生成在加载时链接到 /system/lib/libz.so 的模块:
LOCAL_LDLIBS := -lz
说白了,就是链接指定的Android库. Android NDK 原生API库
注意 : 该构建变量只对可执行文件和共享库有用,对于静态库无用.
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 模式生成模块的对象文件。
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:
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
定义中。
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
导出依赖项。
例如:
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
指定的文件提取或生成的汇编文件。定义此变量会导致发生以下情况 :
LOCAL_SRC_FILES
中所列任何汇编文件的LOCAL_FILTER_ASM
中执行shell命令,因此会生成另一个临时汇编文件.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 命令,它接受输入文件名作为第一个参数,接受输出文件名作为第二个参数。
例如:
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
。LOCAL_PATH := $(call my-dir)
LOCAL_PATH := $(call my-dir)
# ... declare one module
include $(LOCAL_PATH)/foo/`Android.mk`
LOCAL_PATH := $(call my-dir)
# ... declare another module
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_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
this-makefile
parent-makefile
grand-parent-makefile
import-module
$(call import-module,<name>)
Application.mk
构建配置脚本概览:
Application.mk
指定 ndk-build 的项目级设置。默认情况下,它位于应用项目目录中的 jni/Application.mk 下。
注意:其中许多参数也具有模块等效项。例如,APP_CFLAGS 对应于 LOCAL_CFLAGS。无论何种情况下,特定于模块的选项都将优先于应用级选项。对于标记,两者都使用,但特定于模块的标记将后出现在命令行中,因此它们可能会替换项目级设置。
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
APP_ASFLAGS
ASFLAGS
与 ASMFLAGS
不同。后者专用于 YASM 源文件(请参阅关于 APP_ASMFLAGS
的部分)。
APP_ASMFLAGS
APP_BUILD_SCRIPT
ndk-build
假定 Android.mk
文件位于项目根目录的相对路径 jni/Android.mk
中。Android.mk
文件,请将 APP_BUILD_SCRIPT
设置为 Android.mk
文件的绝对路径。APP_CFLAGS
LOCAL_C_INCLUDES
而不是显式 -I 标记。
APP_CLANG_TIDY
APP_CLANG_TIDY_FLAGS
APP_CONLYFLAGS
APP_CPPFLAGS
APP_CXXFLAGS
APP_CPPFLAGS
应优先于 APP_CXXFLAGS
。APP_CPPFLAGS
相同,但在编译命令中将出现在 APP_CPPFLAGS
之后。例如: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
LOCAL_MODULE
中显示的名称。APP_MODULES
中指定了静态库时,才会构建静态库。APP_MODULES
中构建或列出的模块依赖导入的模块。
APP_OPTIM
release
或 debug
。默认情况下,将构建发布二进制文件。
发布模式会启用优化,并可能生成无法与调试程序一起使用的二进制文件。调试模式会停用优化,以便可以使用调试程序。android:debuggable
将导致此变量默认为 debug
,而不是 release
。通过将 APP_OPTIM
设置为 release
可替换此默认值。APP_PLATFORM
APP_PLATFORM
会声明构建此应用所面向的 Android API
级别,并对应于应用的 minSdkVersion。
如果未指定,ndk-build 将以 NDK 支持的最低 API 级别为目标。最新 NDK 支持的最低 API 级别总是足够低,可以支持几乎所有有效设备。APP_PLATFORM
设置为高于应用的 minSdkVersion 可能会生成一个无法在旧设备上运行的应用。在大多数情况下,库将无法加载,因为它们引用了在旧设备上不可用的符号。APP_PLATFORM
的平台版本。APP_PLATFORM
的下一个可用 API 级别。例如,APP_PLATFORM
为 android-20 时,将使用 android-19,因为 android-20 中没有新的原生 API。APP_PROJECT_PATH
APP_SHORT_COMMANDS
LOCAL_SHORT_COMMANDS
的项目级等效项。如需了解详情,请参阅 Android.mk
中有关 LOCAL_SHORT_COMMANDS
的文档。APP_STL
system STL
。其他选项包括 c++_shared
、c++_static
和 none
。请参阅 NDK 运行时和功能。APP_STRIP_MODE
strip
的参数。默认为 --strip-unneeded
。若要避免剥离模块中的所有二进制文件,请将其设置为 none
。如需了解其他剥离模式,请参阅剥离文档。APP_THIN_ARCHIVE
“True”
。如需了解详情,请参阅 Android.mk
中有关 LOCAL_THIN_ARCHIVE
的文档。APP_WRAP_SH
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_<abi>
可能无法与 APP_WRAP_SH
结合使用。如果有任何 ABI 使用特定于 ABI 的 wrap.sh,所有 ABI 都必须使用该 wrap.sh。
版本号 | 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-witch.cmd是适用于GCC系列的调试选择工具,对于LLVM不适用,而现在ndk又使用LLVM做编译器,弃用了GCC,那么这个调试工具之应用于GCC所构建的项目之中,因此,其也要被废弃。
本副本只是一个个人研究的版本,
如若用于商业用途,请使用Android官方发布的正式版本.
请勿将本版本ndk用于商业用途.
NDK 文档, 教程, 还有API的信息可以访问 我们的网站.
NDK 代码示例可以访问 GitHub.
关于Android Studio的信息可以访问 Android Studio 网页.
只要能运行,谁在乎???
NDK bugs should be filed on GitHub.
Android Studio and Gradle bugs should be filed in the Android Studio Bug Tracker. For the fastest response, make sure you follow their guide on Filing Bugs.
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。