前言
CMake 是一个高效的C/C++ 代码(包括 JNI 开发)编译工具,而CMake 的使用,作为开发者最关心的就是如何编写 CMakeLists.txt 。今天就以Android studio这个开发工具为例,详细介绍一下如何在Android studio这个开发工具中使用CMake。首先需要了解一下如何在 gradle文件中配置这些参数。
gradle中常用配置参数
首先我们需要在项目的根目录的build.gradle这个文件中添加先关的配置以及CMakeLists.txt 文件的路径。如下所示:
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
apply plugin: 'org.greenrobot.greendao'
apply plugin: 'kotlin-kapt'
android {
defaultConfig {
externalNativeBuild {
//cmake 的参数配置入口
cmake {
// 指定一些编译选项
cppFlags "-std=c++11 -frtti -fexceptions"
//如何向变量传递参数,对应的格式如下(arguments "-D变量名=参数")
arguments '-DANDROID_PLATFORM=android-24', '-DANDROID_STL=c++_static', '-DANDROID_STL=c++_shared'
// 也可以使用下面这种语法向每个变量传递多个参数(参数之间使用空格隔开),格式如下
// arguments "-D变量名=参数1 参数2"
arguments "-DANDROID_CPP_FEATURES=rtti exceptions"
}
}
ndk {
moduleName "bndLPRNcnnJniLog"
ldLibs "log", "z", "m"
// 指定ABI对应的ARM架构
abiFilters "armeabi-v7a", "arm64-v8a"
}
}
buildTypes {.......}
externalNativeBuild {
cmake {
//CMakeLists.txt文件的路径
path "src/main/cpp/CMakeLists.txt"
//指定Cmake的版本
version "3.10.2"
}
}
sourceSets {
main {
jniLibs.srcDirs = ['libs']
}
}
repositories {
flatDir {
dirs 'libs'
}
}
}
dependencies {
//省略.......
}
CMake 编译 NDK 所支持的变量配置
变量名称 | 参数 | 参数说明 |
---|---|---|
ANDROID_TOOLCHAIN | clang (default) gcc (deprecated) | 指定 Cmake 编译时所使用的工具链。支持gcc和clang俩种工具链,默认使用clang.使用示例:arguments “-DANDROID_TOOLCHAIN=clang” |
ANDROID_PLATFORM | Android对应的API版本 | 指定 NDK 所用的安卓的版本是多少。使用示例:arguments "-DANDROID_PLATFORM=android-21 |
ANDROID_STL | gnustl_static(default)(详细见下面的c++库附表) | 指定 Cmake 编译所使用的标准模版库。使用示例:arguments “-DANDROID_STL=gnustl_static” |
ANDROID_PIE | ON (android-16 以上默认为 ON)OFF (android-15 以下默认为 OFF) | 使得编译的 elf 文件可以加载到内存中的任意位置就叫 pie(position independent executables),出于安全保护,在 Android 4.4 之后可执行文件必须是采用PIE编译。使用示例:arguments “-DANDROID_PIE=ON” |
ANDROID_CPP_FEATURES | 1:空(default) 2:RTTI(支持 RTTI) 3:exceptions(支持 C++ 异常) | 指定是否需要支持 RTTI(RunTime Type Information)和 C++ 的异常,默认为空, 使用示例:arguments “-DANDROID_CPP_FEATURES=rtti exceptions” |
ANDROID_ALLOW_UNDEFINED_SYMBOLS | TRUE 或者FALSE(默认为FALSE) | 指定在编译时,如果遇到未定义的引用时是否抛出错误。如果要允许这些类型的错误,请将该变量设置为 TRUE。使用示例:arguments “-DANDROID_ALLOW_UNDEFINED_SYMBOLS=TRUE” |
ANDROID_ARM_MODE | 1:arm 2: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;标准库 |
推荐博文
关于cmake的知识有好多,这里推荐一个比较的博主,里面详细讲解了NDK开发先关知识。