GNU工具链系列(三): CMake 编译工具
- 概述
- 最小项目
- 变量操作
- 交互操作
- 构建控制
- 安装控制
- 静态库与动态库的构建
- 使用外部共享库和头文件
1. 概述
CMake 是一个用来自动生成 makefile 的工具(进一步简化了工程构建的步骤)
CLion 的构建系统就是 CMake,Qt 的构建系统也是类似的 qmake
CLion 可以自动生成 CMake,如果想要更细致的控制工程,还是有必要学一学 CMake 的
本文仅仅是简单总结了一下,更详细的内容还是要参考书
参考资料:\<\
2. 最小项目
示例 CMakeLists.txt
1 | # 声明当前 cmake 项目的名称及其语言(语言可以不声明) |
执行下列命令使用这个 CMakeLists.txt 编译一个 main.c 文件
1 | 对当前文件夹运行 cmake |
3. 变量操作
设置与使用变量的语法为
1 | # 其中 VALUE 可以为多个值 |
CMake 会自动初始化几个变量的值
1 | # 源码和生成目标目录 |
4. 交互操作
可以使用 MESSAGE 命令向终端发出信息
1 | # SEND_ERROR:产生错误,生成过程被跳过 |
5. 构建控制
ADD_EXECUTABLE 命令指定当前项目要生成的可执行文件及其依赖
1 | ADD_EXECUTABLE(hello [src...]) |
可以使用 ADD_SUBDIRECTORY 指令控制源码和目标文件的位置(外部构建)
1 | # 添加源代码和目标文件的目录 |
可以通过 SET 指令设置特殊变量指定可执行文件和库文件的路径
1 | # 这里主要是分离产生的可执行文件和库文件 |
6. 安装控制
安装控制通过一个命令和一个特殊变量来实现
CMAKE_INSTALL_PREFIX 变量定义了安装部分的前缀部分,可以手动指定一个默认值,也可以在执行 cmake 命令的时候手动传入 CMAKE_INSTALL_PREFIX 参数,如:
1 | # 具体方式可以参考 cmake 的 man 手册 |
然后是 INSTALL 命令,可以指定二进制文件,静态库,动态库,文件,目录以及脚本的安装规则,完整格式如下:
安装目标文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19# targets就是 ADD_EXECUTABLE 或者 ADD_LIBRARY 定义的目标文件
# 可能是可执行二进制(RUNTIME),动态库(LIBRARY),静态库(ARCHIVE)
# 如果 DESTINATION 是绝对路径,则 CMAKE_INSTALL_PREFIX 变量无效
# 否则最终安装路径为 ${CMAKE_INSTALL_PREFIX}/<DESTINATION>
# 当 targets 有多个的时候,可以写多个可选内容为每个 target 指定一套安装规则
INSTALL(
TARGETS targets...
[
[ARCHIVE|LIBRARY|RUNTIME]
[DESTINATION <dir>]
[PERMISSIONS permissions...]
[
CONFIGURATIONS
[Debug|Release|...]
]
[COMPONENT <component>]
[OPTIONAL]
] [...]
)安装普通文件
1
2
3
4
5
6
7
8
9
10# 如果不指定权限,则默认权限为644
INSTALL(
FILES files...
DESTINATION <dir>
[PERMISSIONS permissions...]
[CONFIGURATIONS [Debug|Release|...]]
[COMPONENT <component>]
[RENAME <name>]
[OPTIONAL]
)安装非目标文件的可执行程序安装(比如脚本之类)
1
2
3
4
5
6
7
8
9
10# 与普通文件类似,但默认权限为755
INSTALL(
PROGRAMS files...
DESTINATION <dir>
[PERMISSIONS permissions...]
[CONFIGURATIONS [Debug|Release|...]]
[COMPONENT <component>]
[RENAME <name>]
[OPTIONAL]
)安装目录
1
2
3
4
5
6
7
8
9
10
11
12
13
14INSTALL(
DIRECTORY dirs...
DESTINATION <dir>
[FILE_PERMISSIONS permissions...]
[DIRECTORY_PERMISSIONS permissions...]
[USE_SOURCE_PERMISSIONS]
[CONFIGURATIONS [Debug|Release|...]]
[COMPONENT <component>]
[
[PATTERN <pattern> | REGEX <regex>]
[EXCLUDE]
[PERMISSIONS permissions...]
] [...]
)安装命令
1
2
3
4
5
6
7
8# SCRIPT 指定 CMake 脚本文件(.cmake 文件)
# CODE 指定 CMake 命令(双引号括起来)
# 如 INSTALL(CODE "MESSAGE(\"Sample install message.\")")
INSTALL(
[
[SCRIPT <file>] | [CODE <code>]
] [...]
)7. 静态库与动态库的构建
使用 ADD_LIBRARY 控制构建库文件
1 | # 可以编译动态库(SHARED),静态库(STATIC),MODULE选项可以暂时忽略 |
但是 ADD_LIBRARY 命令要求 libname 唯一,也就不能用两个 ADD_LIBRARY 生成同名静态库和动态库了
可以使用 SET_TARGET_PROPERTIES 命令在生成一个库的时候指定另一种同名库的生成
1 | # 为一个目标设置属性 |
为了同时生成动静两个库,可以组合使用如下指令:
1 | # 生成动态库 |
8. 使用外部共享库和头文件
INCLUDE_DIRECTORIES 命令让我们可以找到非标准位置的头文件
1 | # 默认行为是加入的头文件最后搜索(即AFTER),加入BEFORE参数可以让我们的头文件最先被搜索 |
只有头文件的话,在链接步骤会触发错误,有两个命令可以指定链接库位置
1 | # 直接添加一个目录为链接库搜索路径 |
同时还可以使用两个特殊变量指定头文件和库的路径
1 | # 这两个变量不是CMake变量,而是环境变量,也就是bash传进来的变量 |