基础选项和设置
指令 | 含义 |
---|---|
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()
FetchContent
purpose
- Integrates dependencies at configure time, avoiding the need for pre-installed libraries.
- Helps manage specific versions of dependencies, ensuring consistent builds across different environments.
- Allows you to incorporate libraries that do not have native CMake support by adding custom build steps.
basic usage
include(FetchContent)
# Defines the properties of the content, such as the URL, branch, tag, or commit if it’s a Git repository.
FetchContent_Declare(
googletest
GIT_REPOSITORY https://github.com/google/googletest.git
GIT_TAG release-1.11.0
)
# Downloads, extracts, and makes the content available as a CMake target.
FetchContent_MakeAvailable(googletest)
# Now the googletest library is available in your CMake project, and you can link it as you would any other CMake target:
target_link_libraries(your_project PUBLIC gtest gtest_main)
other commands and options
command/option | meaning |
---|---|
FetchContent_GetProperties |
Retrieves properties of the downloaded content, allowing conditional checks (e.g., checking if content has already been downloaded) |
FetchContent
is highly useful for modern CMake projects, particularly when you want a lightweight, source-integrated dependency management system.
其它
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 开头的定义 |
check_symbol_exists(SYMBOL HEADER VARIABLE) |
determine whether a specific symbol (e.g., a function, macro, or variable) exists in a given header file or set of source files. It is often used in configuration scripts to check for system features or library support during the build process. |
消息打印
使用方法message([<mode>] "message to display" ...)
mode | 含义 |
---|---|
FATAL_ERROR |
停止编译和生成 |
SEND_ERROR |
继续编译,但是停止生成 |
WARNING |
继续编译和生成 |
(none) or NOTICE |
默认是NOTICE模式,不影响编译和生成 |
STATUS |
编译时状态信息,左边以–开头 |
`` | |
`` | |
`` |
generator
expression | meaning |
---|---|
BUILD_INTERFACE |
Refers to the directories to be used during the build phase of the project. It is useful for adding include paths that are valid only while the project is being built. |
INSTALL_INTERFACE |
Refers to the directories to be used after the project has been installed. It is useful for specifying include paths as they will appear in the installation directory. |
These expressions allow you to:
- Provide a clear separation between the development environment (build tree) and the consumer’s environment (install tree).
- Avoid exposing unnecessary or irrelevant paths to end-users who consume the installed package.
示例
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)
Explanation:
OUTPUT
specifies the file to be generated by this command.COMMAND
${PYTHON_EXECUTABLE}
ensures the correct Python interpreter is used (typically resolved using find_package(Python) or find_program).DEPENDS some_target
specifies dependencies for this custom command. The command will be executed ifsome_target
is rebuilt, ensuring the generated file is kept up to date.
an example to run a shell during campilation.
add_custom_command(
OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/include/Generated.hpp"
COMMAND bash "${CMAKE_CURRENT_SOURCE_DIR}/scripts/GenerateHeader.sh" --argument
DEPENDS some_target
)
3. uninstall
xargs -a install_manifest.txt rm -v