基础选项和设置
指令 | 含义 |
---|---|
add_compile_options |
设置编译选项 |
set(CMAKE_CXX_FLAGS [options]) |
针对C++编译器设置编译选项 |
set(CMAKE_CXX_FLAGS_DEBUG [options]) |
对C++在Debug模式下的编译选项 |
set(CMAKE_CXX_FLAGS_RELEASE [options]) |
针对C++在Release模式下的编译选项 |
set(CMAKE_EXPORT_COMPILE_COMMANDS ON) |
生成compile_commands.json文件 |
set(CMAKE_C_FLAGS [options]) |
针对C编译器设置编译选项 |
project(name VERSION 1.0) |
设定工程名和版本号 |
set (name_VERSION_MAJOR 1) |
设置版本号 |
`` |
可以使用set(CMAKE_CXX_STANDARD 11)
和set(CMAKE_CXX_STANDARD_REQUIRED ON)
来全局指定使用C++11标准。
编译选项 | 含义 |
---|---|
-std=c++11 |
|
-Wall |
|
-pthread |
|
-fexceptions |
|
`` |
.
├── app # 存放可执行文件,调用各个模块
├── build # 存放编译生成文件
├── cmake # 存放.cmake文件,查找依赖库
├── CMakeLists.txt # 工程编译规则
├── config # 存放配置文件,硬件参数和软件参数分开保存
├── doc # 存放各个模块的开发文档
├── docker # 存放Docker镜像
├── include # 存放头文件,模块化
├── launch # 存放.launch文件,启动ROS功能包的各个节点
├── LICENSE # 开源协议
├── log # 存放日志文件
├── msg # 存放.msg文件,自定义ROS消息类型
├── package.xml # 依赖的ROS功能包
├── README.md # 工程说明文档
├── rviz_cfg # 存放.rviz文件,配置Rviz可视化参数
├── scripts # 存放Python脚本,用于后处理和可视化
├── src # 存放源文件,模块化,编译成库
│ ├── algorithm # 基础算法,滤波器、最近邻、RANSAC、样条曲线等
│ ├── CMakeLists.txt # 添加子目录
│ ├── common # 模块间共用的类、函数、常量等
│ ├── slam # SLAM算法,激光、视觉、时间同步、位姿估计
│ └── ui # 可视化界面
├── test # 存放单元测试文件,测试各个模块
└── third_party # 存放非本地安装的第三方库
常用变量
路径
变量 | 含义 |
---|---|
CMAKE_HOME_DIRECTORY |
指向了包含顶级CMakeLists.txt文件的目录 |
CMAKE_CURRENT_SOURCE_DIR |
当前正在被处理的CMakeLists.txt文件的目录 |
EXECUTABLE_OUTPUT_PATH 和LIBRARY_OUTPUT_PATH |
重新定义最终结果的存放目录 |
PROJECT_SOURCE_DIR |
当前工程最上层的目录 |
PROJECT_BINARY_DIR |
当前工程的构建目录 |
CMAKE_CURRENT_LIST_FILE |
path of current cmake file |
`` | |
`` |
系统信息
变量 | 含义 |
---|---|
CMAKE_SYSTEM |
当前操作系统的名称和版本 |
CMAKE_SYSTEM_NAME |
当前操作系统的名称 |
CMAKE_SYSTEM_VERSION |
当前操作系统的版本 |
CMAKE_SYSTEM_PROCESSOR |
处理器名称 |
UNIX |
在所有的类 UNIX 平台为 TRUE |
WIN32 |
在所有的 win32 平台为 TRUE |
PROJECT_NAME |
通过PROJECT 指令定义的项目名称 |
`` |
常用指令
查找和路径
在安装第三方依赖库时,相关.cmake文件的路径会写入XXX_DIR环境变量中,find_package()通过查找XXX_DIR环境变量的值来查找上述.cmake文件,进而查找库文件的位置。
指令 | 含义 |
---|---|
find_package(<PackageName> [version]) |
查找包的绝对路径 |
find_library |
查找库的绝对路径 |
link_directories |
将库链接到该命令之后生成的所有目标,包括库和可执行文件 |
include_directories |
将给定目录添加到编译器用来搜索包含文件的目录中,相对路径为当前CMakeLists文件所在路径 |
XXX_FOUND |
XXX是否找到 |
XXX_DIR |
XXX的查找路径 |
XXX_VERSION |
XXX库的头文件路径 |
XXX_LIBRARY_DIRS |
XXX库的链接路径 |
XXX_LIBRARIES |
XX库的库文件名 |
依赖和添加
指令 | 含义 |
---|---|
add_executable(target 1.cpp 2.cc) |
把指定的源文件生成为可执行程序 |
add_library(target SHARE 1.cpp 2.cc) |
将指定的源文件生成为库文件,过程中引用的库文件文动态链接。把SHARE改为STATIC则为静态链接 |
add_dependencies |
定义 target 依赖的其他 target,确保在编译本 target 之前,其他的 target 已经被构建 |
target_link_libraries(target lib1 lib2) |
将指定的库链接到目标文件,目标文件是可执行程序或库 |
target_include_directories(target xxx_dir) |
指定编译目标需要包含的头文件目录 |
文件
指令 | 含义 |
---|---|
aux_source_directory(. DIR_SRCS) |
查找当前目录下的所有源文件,并将名称保存到DIR_SRCS 变量 |
add_subdirectory(dir) |
添加一个文件夹进行编译,该文件夹下的 CMakeLists.txt 负责编译该文件夹下的源码 |
`` |
语法
if
if(VAR1 MATCHES "Hello")
message("this is hello")
message("this is hello2")
elseif(NOT VAR2 MATCHES "world")
message("this is world")
message("this is world2")
endif()
IF(EXISTS dir AND var1)
endif()
while
foreach
在foreach
循环中,支持break
和continue
。
set(mylist "a" "b" c "d") # 生成 list 类型的变量
foreach(_var ${mylist})
message("当前变量是:${_var}")
endforeach()
其它
CMake中,变量的值要么是String要么是String组成的List。
指令 | 含义 |
---|---|
configure_file(config.h.in config.h) |
将一份文件拷贝到另一个位置并修改它的内容,使得在代码中使用CMake中定义的变量 |
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O3") |
追加 |
set(CMAKE_CXX_FLAGS "-O3") |
覆盖 |
add_definitions(-DFOO -DBAR ...) |
用于为编译指令添加-D 开头的定义 |
`` |
消息打印
使用方法message([<mode>] "message to display" ...)
mode | 含义 |
---|---|
FATAL_ERROR |
停止编译和生成 |
SEND_ERROR |
继续编译,但是停止生成 |
WARNING |
继续编译和生成 |
(none) or NOTICE |
默认是NOTICE模式,不影响编译和生成 |
STATUS |
编译时状态信息,左边以–开头 |
`` | |
`` | |
`` |
示例
1. 配置时执行一个命令
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 failed with ${GIT_SUBMOD_RESULT}, please checkout submodules")
endif()
endif()
2. 编译时运行一个命令
add_custom_command(OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/include/Generated.hpp"
COMMAND "${PYTHON_EXECUTABLE}" "${CMAKE_CURRENT_SOURCE_DIR}/scripts/GenerateHeader.py" --argument
DEPENDS some_target)