cmake
概念
CMake是一个跨平台
的安装(编译)工具,可以用简单的语句来描述所有平台的安装(编译过程)。
- 它可以根据
不同平台
、不同的编译器
,生成相应的Makefile或者vcproj项目,通过编写CMakeLists.txt
,可以控制生成的Makefile
,从而控制编译过程。CMake自动生成的Makefile不仅可以通过make命令构建项目
生成目标文件,还支持安装(make install)
、测试安装的程序
是否能正确执行(make test,或者ctest)、生成当前平台的安装包
(make package)、生成源码包
(make package_source)、产生Dashboard显示数据并上传等高级功能,只要在CMakeLists.txt中简单配置
,就可以完成很多复杂的功能,包括写测试用例。
如果有嵌套目录,子目录下可以有自己的CMakeLists.txt。
优点
- 使用 cmake 很简单,只需要执行 cmake, make 两个命令
- 用于编写CMakeLists.txt文件的语言具有可读性和很容易理解。
- 不仅可以使用“Make” 来构建工程。还支持多种生产工具,比如Xcode, Eclipse, Visual Studio, etc.
CMake与Make对比具有以下优点:
- 自动发现跨平台系统库。
- 自动发现和管理的工具集
- 更容易将文件编译进共享库, 以一种平台无关的方式或者以比make更容易使用的的生成方式。
- CMake不仅仅只“make”,所以它变得更复杂。从长远来看,最好能够学会使用它。如果你仅仅在一个平台上构建小的工程,“Make”更适合完成这部分工作。
cmake的使用步骤
一般用cmake生成Makefile的步骤如下
- 编写CMakeList.txt文件
- 执行cmake命令生成Makefile文件
- 使用make命令进行编译
CMakeList文件解析
- 版本
# 首先定义cmake版本
cmake_minimum_required(VERSION 3.4.1)
- 显示更多build信息
set(CMAKE_VERBOSE_MAKEFILE on)
在预设的情况下,CMake 生成的 makefile 只会显示编译的进度,并不会把各步骤实际调用的命令、参数一一列出,但在很多时候我们需要确知编译时倒底使用了哪些编译选项。其中一个方法是直接在 CMakeList.txt 当中加入这一行
- find_ibrary
# 在指定目录下搜索一个库并保存,语法如下
# 单个
find_library (<VAR> name1 [path1 path2 ...])
# 多个
find_library (
<VAR>
name | NAMES name1 [name2 ...] [NAMES_PER_DIR]
[HINTS path1 [path2 ... ENV var]]
[PATHS path1 [path2 ... ENV var]]
[PATH_SUFFIXES suffix1 [suffix2 ...]]
[DOC "cache documentation string"]
[NO_DEFAULT_PATH]
[NO_CMAKE_ENVIRONMENT_PATH]
[NO_CMAKE_PATH]
[NO_SYSTEM_ENVIRONMENT_PATH]
[NO_CMAKE_SYSTEM_PATH]
[CMAKE_FIND_ROOT_PATH_BOTH |
ONLY_CMAKE_FIND_ROOT_PATH |
NO_CMAKE_FIND_ROOT_PATH]
)
# 例子
# find_library(log-lib
log)
#查找log库,并把log库保存到log-lib,用于我们自己使用,查找的库一般是Android系统的库
cmake会在目录中查找,如果所有目录中都没有,值my_lib就会被赋为NO_DEFAULT_PATH
- set_target_properties
# 语法
set_target_properties(target1 target2 ...
PROPERTIES prop1 value1
prop2 value2 ...)
# 例子
#set_target_properties(mylib
PROPERTIES IMPORTED_LOCATION
${CMAKE_CURRENT_SOURCE_DIR}/src/main/cpp/demo.c)
# ${CMAKE_CURRENT_SOURCE_DIR}表示CMakeList文件的路径,一般它放在app目录下和src文件平级,这句话是设置我们写的demo.c为mylib库,这个mylib最后会通过System.loadLibrary方法加载
- target_link_libraries
# 语法
target_link_libraries(<target> ... <item>... ...)
# 例子
target_link_libraries(mylib
${log-lib} )
# 将目标文件与库文件进行链接,如果在mylib库中药使用到log-lib库的功能,那么需要进行这步操作,一般都是链接系统的lib库到我们自己实现的lib库进行调用
这些就是ndk常用的cmake方法,当然更全的cmake文档还需要看官方文档
网友评论