CMake 是一个高效的 C/C++ Makefile 生成工具,具有很好的跨平台性。利用它可以让代码在各个平台上顺利的编译。
现在最愿意看到的编译流程就是:
mkdir build
cd build
cmake ..
make
这里可能不是详尽的解释,但是展示了我本人在编写中常用的命令。
利用 CMake 的契机主要是想要摆脱 XCode 以及使用 CLion。当然,也是为自己的一些小项目做管理。(主要是不想写 MakeFile)
CMakeLists.txt
CMakeList.txt
是 CMake 的核心文件,所有对 CMake 的编辑配置都集中于此。所以,使用 CMake 来管理你的项目核心就在如何编写 CMakeLists.txt
。
具体参考教程可以查看参考资料的第一条进行练习。
常用指令
括号中的是可选项。
version
cmake_minimum_required(VERSION 3.9)
指定 CMake 的最低版本,非必要,但是最好有,因为可能有兼容性问题。
project
project( ProjectName )
指明 CMakeLists.txt
目录是一个项目,并且项目名为指定的名称。CLion 依靠此命令来识别项目。
set
set( )
设置变量命令,类似代码中的变量,可以设置成想要的字符串。
find_package
find_package( [REQUIRED])
查找库的命令。
库一般会有二进制文件以及头文件两个内容需要查找。
此命令会以两种模式寻找库的信息。一种以 Module 模式查找,该命令会从 CMAKE_MODULE_PATH
变量存储的路径(可以包含多个路径,以 : 分隔)中查找格式为 Find
的文件,根据包名来加载对应的 cmake 文件查找对应的内容。具体路径可以查看cmake的查询目录结构。
如果加载完成,以下变量就会被设置为对应的查找路径:
_FOUND
_INCLUDE_DIR
_LIBRARIES
如果上述模式没有查找成功,会进入 Config 模式,会在提供的 path 中查找
或者
来读取配置。如果加载完成,同样会设置上诉的三个变量。
当然还有更复杂的用法以及更多的变量设置,但是简单实用的是上面三个。
PkgConfig
find_package(PkgConfig REQUIRED)
加载这个包会加载一些 cmake 命令,从而可以加载由 pkg-config 管理的库。
加载这个库后会引用三个命令可供使用:
pkg_search_module()
pkg_check_module()
pkg_get_variable()
主要讨论 pkg_search_module
:
用法如下:
pkg_search_module( [比较符 版本号] ...)
可以同时查找多个库,继续往后写就行。
所有库都找到以后,一下变量会被设置:
_FOUND ... set to 1 if module(s) exist
_LIBRARIES ... only the libraries (without the '-l')
_LINK_LIBRARIES ... the libraries and their absolute paths
_LIBRARY_DIRS ... the paths of the libraries (without the '-L')
_LDFLAGS ... all required linker flags
_LDFLAGS_OTHER ... all other linker flags
_INCLUDE_DIRS ... the '-I' preprocessor flags (without the '-I')
_CFLAGS ... all required cflags
_CFLAGS_OTHER ... the other compiler flags
可以根据需要选用,用的比较多应该还是一下两个:
_INCLUDE_DIRS ... the '-I' preprocessor flags (without the '-I')
_LIBRARIES ... only the libraries (without the '-l')
因为 mac 用 brew 安装一些库的时候有时并不会包含
FINDXXX.cmake
,但是xxx.pc
是被正确设置了的。使用pkg-config --list-all
可以查看是否成功安装。
include_directories
include_directories()
指定头文件的搜索路径。外部路径最好使用 <>
引用,虽然使用 ""
也没什么问题,工程目录的最好使用 ""
引用。
aux_source_directory
aux_source_directory( )
该命令会搜索该目录下的所有源文件,组织过后全都放在变量中。防止重复修改配置文件的利器。
add_executable
add_executable( ...)
将多个源文件编译链接成一个可执行文件。这个目录下的 cmake 文件的主要目标,可以设置多个可执行文件。根据需要进行编译。
target_link_libraries
target_link_libraries( )
将库与可执行文件进行链接。
add_subdirectory
add_subdirectory()
这种情况下,path 下也有一个 CMakeLists.txt
来配置子目录的行为,子目录的配置会被加载并将相关的内容添加到当前的配置中。
二进制库相关
add_library
add_library( [STATIC | SHARED | MODULE] )
用法与 add_executable
相似,不过根据需求可以选择生成静态库还是共享库还是模块。
常用模板
下面是管理一个小项目的 cmake 模板,可以根据自己的需求进行修改。如果项目更加复杂,cmake 也可像脚本一样使用循环判断等功能。玩的开心
cmake_minimum_required(VERSION 3.9)
project(Template)
// find_package() 等等
// source dir
aux_source_directory(./src SRC)
// include path
include_directories(./include)
// cmake config
set(CMAKE_CXX_STANDARD 11)
// add exec
add_executable(${EXEC} ${SRC})
// link target
//target_link_libraries(${EXEC} ...)
参考资料
- CMake 入门实战
- find_package CMake docs
- FindPkgConfig