1. CMake 简介
CMake 是一个开源的跨平台自动化构建工具,优点包括:跨平台支持、简化配置、自动化构建、灵活性。
其基本工作流程,如下图:
- 编写 CMakeList.txt 文件:定义项目的构建规则和依赖关系
- 生成构建文件
- 执行构建
2. CMake 基础
CMakeLists.txt
CMakeLists.txt 是 CMake 的配置文件,用于定义项目的构建规则、依赖关系、编译选项等。每个 CMake可以有一个或多个该文件。
文件结构和基本语法
常见指令:
指定 CMake 的最低版本要求
cmake_minimum_required(VERSION 3.10)
定义项目名称和使用的编程语言
project(MyProject CXX)
指定要生成的可执行文件和其源文件
add_executable(<target> <source_files> ...)
创建一个库(静态库或者动态库)及其源文件
add_library(<target> <source_files>...)
链接目标文件与其他库
target_link_libraries(<target> <libraries>...)
添加头文件搜索路径
include_directories(<dirs>...)
,例如include_directories(${PROJECT_SOURCE_DIR}/include)
设置变量的值
set(<variable><value>)...
,如set(CMAKE_CXX_STANDARD 11)
安装规则:
1
2
3
4
5
6
7install(TARGETS target1 [target2 ...]
[RUNTIME DESTINATION dir]
[LIBRARY DESTINATION dir]
[ARCHIVE DESTINATION dir]
[INCLUDES DESTINATION [dir ...]]
[PRIVATE_HEADER DESTINATION dir]
[PUBLIC_HEADER DESTINATION dir])如:
install(TARGETS MyExecutable RUNTIME DESTINATION bin)
设置目标属性:
1
2
3
4target_include_directories(TARGET target_name
[BEFORE | AFTER]
[SYSTEM] [PUBLIC | PRIVATE | INTERFACE]
[items1...])如:
target_include_directories(MyExecutable PRIVATE ${PROJECT_SOURCE_DIR}/include)
条件语句(if elseif endif)
自定义命令
1
2
3
4
5
6
7
8
9add_custom_command(
TARGET target
PRE_BUILD | PRE_LINK | POST_BUILD
COMMAND command1 [ARGS] [WORKING_DIRECTORY dir]
[COMMAND command2 [ARGS]]
[DEPENDS [depend1 [depend2 ...]]]
[COMMENT comment]
[VERBATIM]
)如:
1
2
3
4add_custom_command(
TARGET MyExecutable POST_BUILD
COMMAND ${CMAKE_COMMAND} -E echo "Build completed."
)
变量和缓存
CMake 使用变量来存储和传递信息,这些变量可以在 CMakeLists.txt 文件中定义和使用。变量分为普通变量和缓存变量。
变量的定义与使用
- 定义:
set (MY_VAR "Helle CMake")
- 使用:
message(STATUS "Variable MY_VAR is ${MY_VAR}")
缓存变量
缓存变量存储在 CMake 的缓存文件中,用户可以在CMAke配置是修改这些值、缓存变量通常用于用户输入的设置,例如编译选项和路径。
- 定义:
set(MY_CACHE_VAR "DefaultValue" CACHE STRING "A cache variable")
- 使用:
message(STATUS "Cache variable MY_CACHE_VAR is ${MY_CACHE_VAR}")
查找库和包
CMake 通过 find_package()
指令自动检测和配置外部库和包。常用于系统安装的库和第三方库。
基本用法:
1
find_package(Boost REQUIRED)
指定版本:
1
find_package(Boost 1.70 REQUIRED)
查找库并指定路径:
1
find_package(OpenCV REQUIRED PATHS /path/to/opencv)
使用查找到的库:
1
target_link_libraries(MyExcutable Boost::Boost)
设置包含目录和链接目录
1
2inlude_directories(${Boost_INCLUDE_DIRS})
link_directories(${Boost_LIBRART_DIRS})
下面是一个使用第三方库的实例:
1 | cmake_minimum_required(VERSION 3.10) |
3. CMake 构建流程
- 创建构建目录:保持源代码目录整洁,如创建
build
- 使用CMake生成构建文件:配置项目并生成适合执行的构建文件
cmake ..
- 编译和构造:使用生成好的构建文件执行编译和构建
make
- 清理构建文件:删除中间文件和目标文件
- 重新配置和构建:处理项目设置的更改
4. 构建实例
1 | MyProject/ |
创建 CMakeLists.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16cmake_minimum_required(VERSION 3.10)
project(MyProject VERSION 1.0)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
# 设置头文件搜索目录
include_directories(${PROJECT_SOURCE_DIR}/include)
# 添加源文件
add_library(MyLib src/mylib.cpp) # 创建一个库目标 MyLib
add_executable(MyExecutable src/main.cpp) #创建一个可执行文件目标 MyExecutable
# 链接库到可执行文件
target_link_libraries(MyExecutable MyLib)创建构建目录
1
mkdir build && cd build
配置项目
在构建目录(build)使用CMake构建醒目,这将生成适合平台的构建文件(如 Makefile)
1
cmake ..
- cmake ..:指向源代码目录,即包含 CMakeLists.txt 文件的目录。CMake 将读取 CMakeLists.txt 文件并生成构建系统文件。
编译项目
使用生成的构建系统文件编译项目。根据生成的构建文件系统,使用相应的构建命令。
1
make
- make:编译项目并生成可执行文件 MyExecutable
运行可执行文件
1
./MyExecutable
清理构建文件
用于删除生成的中间文件和目标文件
1
make clean