CMakeLists 学习指南
本文最后更新于:2024年2月24日 下午
CMake是一个元(meta)构建系统,可用于为许多其他构建工具创建构建文件。
三天速通!结合UGAS的CMakeLists食用更香捏!
上交教程:
https://sjtu-robomaster-team.github.io/vision-learning-4-cmake-introduction/
完整教程:
https://zhuanlan.zhihu.com/p/367808125
核心语法:
https://zhuanlan.zhihu.com/p/368701263
使用Cmake+VScode编译构建C++文件
- 编写好CMakeLists.txt
- 执行Cmake的confit命令。直接调用命令台工具(
Ctrl + Shift + P
),然后选择Cmake Config
- 点击下面的
build
按钮,编译成功。- 所有的编译后的东西自动被vscode的cmake插件放入了build文件夹中,这个文件夹也是cmake插件自动生成的。
- 运行生成即可run你的工程文件。
速览:处理多源文件目录的方法
1 |
|
- 关键字有三种,PRIVATE | PUBLIC | INTERFACE,不同的关键字在进行CMake编译后会生成不同的include 文件夹
- 在CMake中,变量的使用都是 ${变量名} 这种格式。
- 除了README.md文件是用来讲解的文件外,另外几个文件都是要进行编译的。
- ${PROJECT_SOURCE_DIR}指当前项目的顶级(上级)源目录,则在编写程序时引用include里面的头文件可以直接写头文件名,不用写相对路径了
- ${CMAKE_CXX_FLAGS} C++编译器的编译选项。具体常用选项有:
-rdynamic
通知链接器将所有符号添加到动态符号表,通过使用 dlopen 来实现向后跟踪-O3
开启优化-fPIC
编译器产生与位置无关代码,即产生的代码中全部使用相对地址-ggdb
编译器生成gdb专用的更为丰富的调试信息-std=c++11
-Wall
编译后显示所有警告
(还有一些不太常用的,网址自查:https://blog.csdn.net/m0_51551385/article/details/125083575?ydreferer=aHR0cHM6Ly9jbi5iaW5nLmNvbS8%3D)
编译指令:
1 |
|
编译完成后,在终端输入:
1 |
|
就可以运行程序文件。
高级点的语法:
递归搜索所有的.cpp文件并将列表存储在一个变量中:
1 |
|
CONFIGURE_DEPENDS
告知 CMake 有关配置过程的其他输入文件的信息。如果修改了任何命名文件,生成系统将重新运行 CMake 以重新配置文件并再次生成生成系统。
将文件指定为以分号分隔的路径列表。configure_file
:通过读取输入文件中的内容,将 CMakeLists.txt 文件中的变量转变为 C/C++ 中可识别的宏定义,然后存入输出文件中。具体参考:https://zhuanlan.zhihu.com/p/4369233701
configure_file(<input> <output>)
输入文件为 xxx(目录路径)-config.h.in
输出文件为 xxx-config.h
选项开关:
1 |
|
第一个参数为选项名称。此选项不仅可以是boolean,也可以是string或list。
第二个参数为选项介绍,为string。
第三个参数为选项默认值,依据选项类型设置。
- 条件分支:
1
2
3
4
5
6
7if (CONDITION_1)
# do something
elseif (CONDITION_2)
# do something
else()
# do something
endif()
find_package
查找并载入一个外部包
1 |
|
最常用用法:
find_package(OpenCV 4.7 REQUIRED)
find_package(HikCameraSDK REQUIRED)
查找名为 XX 的包,找不到就报错(并终止 cmake 进程,不再继续往下执行)。
- include_directories
cmake使用 include_directories是用来 提供搜索头文件路径
1 |
|
在ROS2环境下编译:
- 生成目标文件,并且不需要再使用target_link_libraries
1
2
3ament_auto_add_executable
ament_auto_add_library ament_auto_find_build_dependencies
ROS2环境下的链接库方式,相当于不用写find_package了。(ROS之前连接库的指令)ament_auto_package
这个用来代替以前的export(导出库)和两次install(安装库),以及最后的ament_package
link_directories
链接库;添加需要链接的库文件路径之后就可以使用相对路径,使用TARGET_LINK_LIBRARIES时,只需给出动态链接库名即可。target_link_libraries
- 如果所有目标都使用相关的include目录,则需要使用link_libraries;
如果路径是特定于目标,就用target_link_libraries - 如果所有目标都使用相关的include目录,则需要使用link_libraries;
如果路径是特定于目标,就用target_link_libraries
- 如果所有目标都使用相关的include目录,则需要使用link_libraries;
DEBUG
时使用的命令:
打印变量信息
- SET(USER_KEY, “Hello World”)\
#设置变量
- MESSAGE( STATUS “this var key = ${USER_KEY}.”)
- message([
] “message text” …)
UGAS的CMakeLists.txt参考:
1 |
|
使用ninja构建
概念——生成器
CMake生成器负责为底层构建系统编写输入文件(例如Makefile)。
运行cmake--help
将显示可用的生成器。
CMake包括不同类型的生成器,如命令行生成器、IDE生成器和其他生成器。
- 命令行生成工具生成器
这些生成器用于命令行构建工具,如Make和Ninja。 - IDE构建工具生成器
这些生成器用于集成开发环境,其中包括它们自己的编译器。例如Visual Studio和Xcode,它们本身就包含一个编译器。 - 其他生成器
这些生成器创建配置并与其他IDE工具共同工作,并且必须包含在IDE或命令行生成器中。
Note | 在本例中,ninja是通过命令sudo apt-get install ninja-build安装的。 |
---|
调用生成器
1 |
|
CMake将生成所需的Ninja构建文件,这些文件可以通过使用Ninja命令运行。
实例:使用Ninja编译UGAS
1 |
|
tips:
- colcon:使用colcon构建ros包,相当于ros1中的catkin工具
- cp -r Dir/ /home/test :将Dir目录copy到test目录下