CMake教程
CMake教程
王永旺1. 常用的宏
宏 | 功能 |
---|---|
CMAKE_CURRENT_SOURCE_DIR |
当前访问的 CMakeLists.txt 文件所在的路径 |
PROJECT_SOURCE_DIR |
使用cmake命令时,后面紧跟的目录,一般是工程的根目录 |
EXECUTABLE_OUTPUT_PATH |
指定输出的目录 |
LIBRARY_OUTPUT_PATH |
库目录 |
CMAKE_AUTORCC | 指定CMake是否会自动处理Qt资源文件 |
2. 最简单的CMakeLists.txt文件
1 | # 指定使用的 cmake 的最低版本 |
3. 指定使用的C++标准
1 | #增加-std=c++11 |
4. 指定输出路径
1 | # 指定输出的路径 若不存在会自动生成 |
5. 搜索文件
5.1 aux_source_directory函数
在 CMake 中使用aux_source_directory 命令可以查找某个路径下的所有源文件,命令格式为:
1 | aux_source_directory(< dir > < variable >) |
dir
:要搜索的目录variable
:将从dir
目录下搜索到的源文件列表存储到该变量中
1 | cmake_minimum_required(VERSION 3.8) |
5.2 file函数
1 | file(GLOB/GLOB_RECURSE 变量名 要搜索的文件路径和文件类型) |
GLOB
: 将指定目录下搜索到的满足条件的所有文件名生成一个列表,并将其存储到变量中。GLOB_RECURSE
:递归搜索指定目录,将搜索到的满足条件的文件名生成一个列表,并将其存储到变量中。
1 | file(GLOB MAIN_SRC ${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp) |
6. 包含头文件
1 | include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include) |
7. 创建库
1 | add_library(<target> <source_files>...) |
7.1 制作静态库
1 | add_library(calc STATIC ${SRC_LIST}) |
7.2 制作动态库
1 | add_library(calc SHARED ${SRC_LIST}) |
7.3 指定输出的路径
方式1-适用于动态库
对于生成的库文件来说和可执行程序一样都可以指定输出路径。由于在Linux下生成的动态库默认是有执行权限的
,所以可以按照生成可执行程序的方式去指定它生成的目录:
1 | cmake_minimum_required(VERSION 3.0) |
方式2-都适用
由于在Linux下生成的静态库默认不具有可执行权限,所以在指定静态库生成的路径的时候就不能使用EXECUTABLE_OUTPUT_PATH
宏了,而应该使用LIBRARY_OUTPUT_PATH
,这个宏对应静态库文件和动态库文件都适用
。
1 | cmake_minimum_required(VERSION 3.0) |
8. 包含库文件
8.1 链接静态库
1 | link_libraries(<static lib> [<static lib>...]) |
用于设置全局链接库,这些库会链接到之后定义的所有目标上。
参数1:指定出要链接的静态库的名字
参数2-N:要链接的其它静态库的名字
如果该静态库不是系统提供的(自己制作或者使用第三方提供的静态库)可能出现静态库找不到的情况,此时可以将静态库的路径也指定出来:
1 | link_directories(<lib path>) |
1 | cmake_minimum_required(VERSION 3.0) |
8.2 链接动态库
1 | target_link_libraries( |
用于指定一个目标(如可执行文件或库)在编译时需要链接哪些库。它支持指定库的名称、路径以及链接库的顺序。
target
:指定要加载的库的文件的名字
该文件可能是一个源文件
该文件可能是一个动态库/静态库文件
该文件可能是一个可执行文件
PRIVATE|PUBLIC|INTERFACE
:动态库的访问权限,默认为PUBLIC
如果各个动态库之间没有依赖关系,无需做任何设置,三者没有没有区别,
一般无需指定,使用默认的 PUBLIC 即可
。动态库的链接具有传递性
,如果动态库 A 链接了动态库B、C,动态库D链接了动态库A,此时动态库D相当于也链接了动态库B、C,并可以使用动态库B、C中定义的方法。
1 | target_link_libraries(A B C) |
PUBLIC
:在public后面的库会被Link到前面的target中,并且里面的符号也会被导出,提供给第三方使用。PRIVATE
:在private后面的库仅被link到前面的target中,并且终结掉,第三方不能感知你调了啥库INTERFACE
:在interface后面引入的库不会被链接到前面的target中,只会导出符号。
链接系统动态库
动态库的链接和静态库是完全不同的:
静态库会在生成可执行程序的链接阶段被打包到可执行程序中,所以可执行程序启动,静态库就被加载到内存中了。
动态库在生成可执行程序的链接阶段不会被打包到可执行程序中,当可执行程序被启动并且调用了动态库中的函数的时候,动态库才会被加载到内存
因此,在cmake
中指定要链接的动态库的时候,应该将命令写到生成了可执行文件之后
:
1 | cmake_minimum_required(VERSION 3.0) |
在target_link_libraries(app pthread)
中:
app
: 对应的是最终生成的可执行程序的名字pthread
:这是可执行程序要加载的动态库,这个库是系统提供的线程库,全名为libpthread.so
,在指定的时候一般会掐头(lib)去尾(.so)。
链接第三方动态库
1 | cmake_minimum_required(VERSION 3.0) |
建议在 CMake 项目中优先使用 target_link_libraries
9. 日志
在CMake中可以用用户显示一条消息,该命令的名字为message
:
1 | message([STATUS|WARNING|AUTHOR_WARNING|FATAL_ERROR|SEND_ERROR] "message to display" ...) |
(无) :重要消息
STATUS :非重要消息
WARNING:CMake 警告, 会继续执行
AUTHOR_WARNING:CMake 警告 (dev), 会继续执行
SEND_ERROR:CMake 错误, 继续执行,但是会跳过生成的步骤
FATAL_ERROR:CMake 错误, 终止所有处理过程
CMake的命令行工具会在stdout上显示STATUS消息,在stderr上显示其他所有消息。CMake的GUI会在它的log区域显示所有消息。
CMake警告和错误消息的文本显示使用的是一种简单的标记语言。文本没有缩进,超过长度的行会回卷,段落之间以新行做为分隔符。
1 | # 输出一般日志信息 |
10. install
install命令用于将文件或目录安装到指定位置,常用于二进制执行文件、动态库、静态库的部署。
install不是自动执行的,需在命令行执行cmake install
选项 | 含义 |
---|---|
RUNTIME | 二进制可执行文件 |
LIBRARY | 动态库 |
ARCHIVE | 静态库 |
1 | install(TARGETS <target_name> |
GNUInstallDirs标准安装目录
目标类型 | GNUInstallDirs变量 | 内置默认值 |
---|---|---|
RUNTIME | ${CMAKE_INSTALL_BINDIR} | bin |
LIBRARY | ${CMAKE_INSTALL_BINDIR} | lib |
ARCHIVE | ${CMAKE_INSTALL_BINDIR} | lib |
PRIVATE_HEADER | ${CMAKE_INSTALL_INCLUDEDIR} | include |
PUBLIC_HEADER | ${CMAKE_INSTALL_INCLUDEDIR} | include |
FILE_SET (头文件类型) | ${CMAKE_INSTALL_INCLUDEDIR} | include |
1 | cmake_minimum_required(VERSION 3.0) |
11. 添加子目录
1 | add_subdirectory(source_dir [binary_dir] [EXCLUDE_FROM_ALL]) |
12. 与Qt相关的变量
UIC(用户界面编译器)、MOC(元对象编译器)和RCC(资源编译器)
12.1 自动处理.ui
文件文件
1 | set(CMAKE_AUTOUIC ON) |
启用了CMake的自动UIC支持。当此选项被设置为ON时,CMake将自动检测项目中的.ui
文件(Qt Designer创建的用户界面文件),并使用UIC工具将这些文件转换成C++源文件,然后这些源文件会被自动添加到相应的Qt目标(如库或可执行文件)的编译过程中。这样,开发者就不需要手动编写CMake脚本来调用UIC或处理其输出文件。
12.2 自动处理继承QObject的类
1 | set(CMAKE_AUTOMOC ON) |
启用了CMake的自动MOC支持。当此选项被设置为ON时,CMake将自动检测项目中继承自QObject
的类(这些类需要使用MOC进行元对象信息的生成),并调用MOC工具来生成必要的元对象代码。这些生成的代码文件随后会被自动添加到项目的编译过程中。这对于使用Qt信号和槽机制、属性系统、事件系统等特性的类来说是必需的。
12.3 自动处理Qt资源文件
1 | set(CMAKE_AUTORCC ON) |
启用了CMake的自动RCC支持。RCC是Qt的资源编译器,用于将.qrc
文件(Qt资源集合文件)编译成二进制格式,这些二进制资源可以在Qt应用程序中动态加载。当CMAKE_AUTORCC
被设置为ON时,CMake会自动检测项目中的.qrc
文件,并使用RCC工具将其编译成资源文件,然后将这些资源文件添加到构建过程中。这简化了管理Qt项目中资源文件的过程。
示例:
1 | cmake_minimum_required(VERSION 3.16) |