基础选项和设置

指令 含义
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_PATHLIBRARY_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循环中,支持breakcontinue

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)