一、简介
在 Android Studio 2.2 以上的版本,推荐使用 CMake 来编译工程里的 C/C++ 代码(包括 JNI 部分)。
一般来言,我们只需要关注和编写 CMakeLists.txt 即可,至于 CMake 如何编译,以及使用的什么样的配置选项是不怎么关心的(会有一系列默认的配置)。不过,如果你需要更改或者定制化一些编译的选项,你就需要了解一下如果在 gradle 中配置这些信息了。
二、如何在 gradle 中使用 cmake 的变量
android {
...
defaultConfig {
...
externalNativeBuild {
cmake {
// 指定一些编译选项
cppFlags "-std=c++11 -frtti -fexceptions"
...
// 也可以使用下面这种语法向变量传递参数:
// arguments "-D变量名=参数".
arguments "-DANDROID_ARM_NEON=TRUE",
// 使用下面这种语法向变量传递多个参数(参数之间使用空格隔开):
// arguments "-D变量名=参数1 参数2"
"-DANDROID_CPP_FEATURES=rtti exceptions"
// 指定ABI
abiFilters "armeabi-v7a" , "arm64-v8a"
}
}
}
buildTypes {...}
externalNativeBuild {
cmake {
path "CMakeLists.txt"
}
}
}
在 Module 级别的 build.gradle 文件中,使用类似上述 cmake 块中形式配置相关参数。
三、CMake 编译 NDK 所支持的变量配置
变量名 | 参数 | 描述 |
ANDROID_TOOLCHAIN | clang (default) gcc (deprecated) | 指定 Cmake 编译所使用的工具链。 使用示例:arguments "-DANDROID_TOOLCHAIN=clang" |
ANDROID_PLATFORM | API版本 | 指定 NDK 所用的安卓平台的版本是多少。 使用示例:arguments "-DANDROID_PLATFORM=android-21" |
ANDROID_STL | gnustl_static(default) | 指定 Cmake 编译所使用的标准模版库。 使用示例:arguments "-DANDROID_STL=gnustl_static" |
ANDROID_PIE | ON (android-16 以上默认为 ON) OFF (android-15 以下默认为 OFF) | 使得编译的 elf 文件可以加载到内存中的任意位置就叫 pie(position independent executables)。 使用示例:arguments "-DANDROID_PIE=ON" |
ANDROID_CPP_FEATURES | 空(default) rtti(支持 RTTI) exceptions(支持 C++ 异常) | 指定是否需要支持 RTTI(RunTime Type Information)和 C++ 的异常,默认为空。 使用示例:arguments "-DANDROID_CPP_FEATURES=rtti exceptions" |
ANDROID_ALLOW_UNDEFINED_SYMBOLS | TRUE FALSE(default) | 指定在编译时,如果遇到未定义的引用时是否抛出错误。如果要允许这些类型的错误,请将该变量设置为 TRUE。 使用示例:arguments "-DANDROID_ALLOW_UNDEFINED_SYMBOLS=TRUE" |
ANDROID_ARM_MODE | arm thumb (default) | 如果是 thumb 模式,每条指令的宽度是 16 位,如果是 arm 模式,每条指令的宽度是 32 位。 使用示例:arguments "-DANDROID_ARM_MODE=arm" |
ANDROID_ARM_NEON | TRUE FALSE(default) | 指定在编译时,是否使用 NEON 对代码进行优化。NEON 只适用于 armeabi-v7a 和 x86 ABI,且并非所有基于 ARMv7 的 Android 设备都支持 NEON,但支持的设备可能会因其支持标量/矢量指令而明显受益。 使用示例:arguments "-DANDROID_ARM_NEON=TRUE" |
ANDROID_DISABLE_NO_EXECUTE | TRUE FALSE(default) | 指定在编译时是否启动 NX(No eXecute)。NX 是一种应用于 CPU 的技术,帮助防止大多数恶意程序的攻击。如果要禁用 NX,请将该变量设置为 TRUE。 使用示例:arguments "-DANDROID_DISABLE_NO_EXECUTE=TRUE" |
ANDROID_DISABLE_RELRO | TRUE FALSE(default) | RELocation Read-Only (RELRO) 重定位只读,它能够保护库函数的调用不受攻击者重定向的影响。如果要禁用 RELRO,请将该变量设置为 TRUE。 使用示例:arguments "-DANDROID_DISABLE_RELRO=FALSE" |
ANDROID_DISABLE_FORMAT_STRING_CHECKS | TRUE FALSE(default) | 在类似 printf 的方法中使用非常量格式字符串时是否抛出错误。如果为 TRUE,即不检查字符串格式。 使用示例:arguments "-DANDROID_DISABLE_FORMAT_STRING_CHECKS=FALSE" |
四、附表(C++ 库支持)
名称 | 说明 | 功能 |
libstdc++ | 默认最小系统 C++ 运行时库 | 不适用 |
gabi++_static | GAbi++ 运行时(静态)。 | C++ 异常和 RTTI |
gabi++_shared | GAbi++ 运行时(共享)。 | C++ 异常和 RTTI |
stlport_static | STLport 运行时(静态)。 | C++ 异常和 RTTI;标准库 |
stlport_shared | STLport 运行时(共享)。 | C++ 异常和 RTTI;标准库 |
gnustl_static | GNU STL(静态)。 | C++ 异常和 RTTI;标准库 |
gnustl_shared | GNU STL(共享)。 | C++ 异常和 RTTI;标准库 |
c++_static | LLVM libc++ 运行时(静态)。 | C++ 异常和 RTTI;标准库 |
c++_shared | LLVM libc++ 运行时(共享)。 | C++ 异常和 RTTI;标准库 |
参考:https://developer.android.com/ndk/guides/cpp-support#system |