现代CMake5-组织你的项目
CMake学习笔记-组织你的项目
现代CMake5-组织你的项目
首先,如果你创建一个名为 project 的项目,它有一个名为 lib 的库,有一个名为 app 的可执行文件,那么目录结构应该如下所示:
- project
- .gitignore
- README.md
- LICENCE.md
- CMakeLists.txt
- cmake
- FindSomeLib.cmake
- something_else.cmake
- include
- project
- lib.hpp
- src
- CMakeLists.txt
- lib.cpp
- apps
- CMakeLists.txt
- app.cpp
- tests
- CMakeLists.txt
- testlib.cpp
- docs
- CMakeLists.txt
- extern
- googletest
- scripts
- helper.py
include中没有CMakeLists.txt文件,为了将其拷贝到/usr/include或者其他类似目录下,避免冲突问题,就不能有除了头文件以外的文件。需要有一个
cmake文件夹,里面包含所有用到的辅助模块。这是你放置所有 Find*.cmake 的文件。你可以在 github.com/CLIUtils/cmake 找到一些常见的辅助模块集合。你可以通过以下语句将此目录添加到你的CMake Path中:1
set(CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake" ${CMAKE_MODULE_PATH})
extern几乎只包含git子模块。
命令比较厉害:
1
2
3
4
5
6
cmake -S . -B build
cmake --build build
# To test (--target can be written as -t in CMake 3.15+):
cmake --build build --target test
# To build docs (requires Doxygen, output in build/docs/html):
cmake --build build --target docs
我们项目底下只有一个 cartographer 的 index/html 。
在CMake中运行其他程序
在配置时运行一条命令
可以在脚本模式下尝试,cmake -P xxx.cmake。
可以使用 execute_process 来运行一条命令并获得他的结果。一般来说,在 CMake 中避免使用硬编码路径是一个好的习惯,你也可以使用 ${CMAKE_COMMAND} ,find_package(Git) , 或者find_program 来获取命令的运行权限。可以使用 RESULT_VARIABLE 变量来检查返回值,使用 OUTPUT_VARIABLE 来获得命令的输出。
书中的例子,有点麻烦,我没有子模块的 git 好像并没有执行。
1
2
3
4
5
6
7
8
9
10
find_package(Git QUIET)
if(GIT_FOUND AND EXISTS "${PROJECT_SOURCE_DIR}/.git")
execute_process(COMMAND ${GIT_EXECUTABLE} submodule update --init --recursive
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
RESULT_VARIABLE GIT_SUBMOD_RESULT)
if(NOT GIT_SUBMOD_RESULT EQUAL "0")
message(FATAL_ERROR "git submodule update --init --recursive failed with ${GIT_SUBMOD_RESULT}, please checkout submodules")
endif()
endif()
几个比较重要的参数:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
execute_process(COMMAND <cmd1> [<arguments>]
[COMMAND <cmd2> [<arguments>]]...
[WORKING_DIRECTORY <directory>]
[TIMEOUT <seconds>]
[RESULT_VARIABLE <variable>]
[RESULTS_VARIABLE <variable>]
[OUTPUT_VARIABLE <variable>]
[ERROR_VARIABLE <variable>]
[INPUT_FILE <file>]
[OUTPUT_FILE <file>]
[ERROR_FILE <file>]
[OUTPUT_QUIET]
[ERROR_QUIET]
[COMMAND_ECHO <where>]
[OUTPUT_STRIP_TRAILING_WHITESPACE]
[ERROR_STRIP_TRAILING_WHITESPACE]
[ENCODING <name>]
[ECHO_OUTPUT_VARIABLE]
[ECHO_ERROR_VARIABLE]
[COMMAND_ERROR_IS_FATAL <ANY|LAST|NONE>])
- WORKING_DIRECTORY :在指定目录执行
- TIMEOUT:子进程超时限制
- RESULT_VARIABLE:接受上一个子进程的结果。它有两种形式:整数,表达错误码;字符串,表达一个错误条件
- OUTPUT_VARIABLE: 接受子进程的标准输出(stdout)
- ERROR_VARIABLE: 接受子进程的标准错误输出(stderr)
例如:
1
2
3
4
5
6
7
8
9
execute_process(
COMMAND echo "world"
RESULT_VARIABLE ECHO_RESULT
OUTPUT_VARIABLE ECHO_OUTPUT
)
if(ECHO_RESULT EQUAL "0")
message(STATUS "${ECHO_OUTPUT}")
endif()
在构建时运行一条命令
CMake 中包含的常用的工具
一个有用的工具是 cmake -E <mode>(在 CMakeLists.txt 中被写作 ${CMAKE_COMMAND} -E)。通过指定后面的 <mode> 允许 CMake 在不显式调用系统工具的情况下完成一系列事情,例如 copy(复制),make_directory(创建文件夹),和 remove(移除) 。