跟我一起学NDK-CMake必知必会
CMake 简介
CMake 构建脚本是一个纯文本文件,您必须将其命名为 CMakeLists.txt,并在其中包含 CMake 构建您的 C/C++ 库时需要使用的命令。如果您的原生源代码文件还没有 CMake 构建脚本,您需要自行创建一个,并在其中包含适当的 CMake 命令
本部分将介绍您应该在构建脚本中包含哪些基本命令,以便指示 CMake 在创建原生库时使用哪些源代码文件。如需了解详情,请参阅 CMake 官方文档: https://cmake.org/cmake/help/latest/manual/cmake-commands.7.html
CMake 常用语法
推荐使用 CMake 3.6.0 的版本,因为默认的 3.10.2 在日志显示上会有问题。在 build.gradle 文件 android 域中修改 CMake 的版本
1 |
|
CMake 的语法具体包含以下几类
- CMake 的基础语法
- c++ 文件编译成 so 的语法
- so 动态库之前相互关联的语法
使用 # 作为注释开头
CMake 指令大小写不敏感,参数和变量大小写敏感
Android 中推荐使用小写
变量使用 ${} 方式取值,但是在 if 控制语句中直接使用变量名
逻辑操作,跟 python 有些类似
1 |
|
可以用于根据不同平台去编译不同平台的 so 库
set 指令
语法:set(VAR [VALUE])
显示定义变量,例如:
1 |
|
message 指令
向终端打印日志:编译过程打印日志;例如:
1 |
|
cmake_minimum_required 指令
规定 CMake 最低版本,例如:
1 |
|
project 指令
定义 CMake 工程名称,例如:
1 |
|
include_directories 指令
语法:include_directories([AFTER | BEFORE] [SYSTEM] dir1 dir2…)
可以用来向工程添加多个特定的头文件搜索路径(可以用<>引用),路径之间用空格分割,如果路径中包含了空格,可以使用双引号将它括起来,默认的行为是追加到当前的头文件搜索路径的后面,例如:
1 |
|
add_library 指令
语法:add_library(name [SHARED | STATIC | MODULE] [EXCLUDE_FROM_ALL] [source])
将一组 cpp 源文件编译出一个库文件,并保存为 libname.so (lib 前缀是生成文件时 CMake 自动添加上去的)。其中有三种库文件类型,不写的话,默认为 STATIC
- SHARED: 表示动态库,可以在(Java)代码中使用 System.loadLibrary(name) 动态调用
- STATIC: 表示静态库,集成到代码中会在编译时调用
- MODULE: 只有在使用 dyId 的系统有效,如果不支持 dyId,则被当作 SHARED 对待
add_library 命令也可以用来导入第三方的库:
add_library(libname [SHARED | STATIC | MODULE | UNKNOWN] IMPORTED)
例如,导入 opencv.so
1 |
|
set_target_properties 指令
语法:set_target_properties(target1 target2 … PROPERTIES prop1 value1 prop2 value2 …)
这条指令可以用来设置输出的名称(设置构建同名的动态库和静态库,或者指定要导入的库文件的路径),例如:
1 |
|
find_library 指令
查找 NDK 已经存在的 so 动态库,例如:
1 |
|
target_link_libraries 指令
语法:target_link_libraries(target library <debug | optimized> library2…)
共享库关联,以便相互调用函数,例如:
1 |
|
经常用的常量
- CMAKE_CURRENT_LIST_FILE 当前 CMake 文件的路径
- CMAKE_CURRENT_LIST_DIR 当前 CMake 文件夹的路径
- ANDROID_ABI 当前在打的 so 对应的 cpu 架构
这些路径对于引用其他的库非常有用
动态库的来源
动态库的来源总共就三类:
- 基于 cpp 源文件打的动态库
1 |
|
- NDK 中查找存在的动态库
1 |
|
- 自己在 jniLibs 中添加的三方动态库
1 |
|
理解示例工程
现在我们再来看下之前示例工程创建的 CMakeLists.txt 的内容就会更加清晰
1 |
|
- 设置了最低的 CMake 版本为 3.10.2
- 将当前 CMake 工程命名为 testndk
- 将 native-lib.cpp 文件打成动态库 libnative-lib.so
- 查找本地 log 库,并重命名为 log-lib
- 将 native-lib 和 log-lib 两个动态库关联,以便在 native-lib.cpp 内部使用 log 库的函数
CMake 构建产物
CMake 构建的产物在 build/intermediates 文件夹下,默认构建所有 cpu 架构的产物
可以在 android 域的 defaultConfig 下指定需要构建的 cpu 架构
1 |
|
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!