CMake学习笔记¶
CMake 是个一个开源的跨平台自动化建构系统,用来管理软件建置的程序,并不依赖于某特定编译器,并可支持多层目录、多个应用程序与多个函数库。
CMake 通过使用简单的配置文件 CMakeLists.txt,自动生成不同平台的构建文件(如 Makefile、Ninja 构建文件、Visual Studio 工程文件等),简化了项目的编译和构建过程。
CMake 本身不是构建工具,而是生成构建系统的工具,它生成的构建系统可以使用不同的编译器和工具链。
CMake 的作用和优势¶
- 跨平台支持: CMake 支持多种操作系统和编译器,使得同一份构建配置可以在不同的环境中使用。
- 简化配置: 通过 CMakeLists.txt 文件,用户可以定义项目结构、依赖项、编译选项等,无需手动编写复杂的构建脚本。
- 自动化构建: CMake 能够自动检测系统上的库和工具,减少手动配置的工作量。
- 灵活性: 支持多种构建类型和配置(如 Debug、Release),并允许用户自定义构建选项和模块。
构建配置¶
- CMakeLists.txt 文件: CMake 的配置文件,用于定义项目的构建规则、依赖关系、编译选项等。每个 CMake 项目通常包含一个或多个 CMakeLists.txt 文件。
- 构建目录: 为了保持源代码的整洁,CMake 鼓励使用独立的构建目录(Out-of-source 构建)。这样,构建生成的文件与源代码分开存放。
安装 CMake¶
CMake 安装包下载地址:https://cmake.org/download/。
选择 Windows 版本的安装包(通常是 .msi 文件)。
下载后,双击下载的 .msi 文件,按照安装向导的指示进行安装。

在安装过程中,可以选择将 CMake 添加到系统的 PATH 环境变量中(建议选择此选项,以便在命令行中直接使用 cmake 命令)。

验证安装:打开命令提示符(CMD)或 PowerShell,输入 cmake --version,查看是否能正确显示 CMake 的版本信息。
CMakeLists.txt 文件¶
CMakeLists.txt 是 CMake 的配置文件,用于定义项目的构建规则、依赖关系、编译选项等。
每个 CMake 项目通常都有一个或多个 CMakeLists.txt 文件。
CMakeLists.txt 文件使用一系列的 CMake 指令来描述构建过程。常见的指令包括:
1、指定 CMake 的最低版本要求:
cmake_minimum_required(VERSION <version>)
cmake_minimum_required(VERSION 3.10)
project(<project_name> [<language>...])
project(MyProject CXX)
add_executable(<target> <source_files>...)
add_executable(MyExecutable main.cpp other_file.cpp)
add_library(<target> <source_files>...)
add_library(MyLibrary STATIC library.cpp)
target_link_libraries(<target> <libraries>...)
target_link_libraries(MyExecutable MyLibrary)
include_directories(<dirs>...)
include_directories(${PROJECT_SOURCE_DIR}/include)
set(<variable> <value>...)
set(CMAKE_CXX_STANDARD 11)
target_include_directories(TARGET target_name
[BEFORE | AFTER]
[SYSTEM] [PUBLIC | PRIVATE | INTERFACE]
[items1...])
target_include_directories(MyExecutable PRIVATE ${PROJECT_SOURCE_DIR}/include)
install(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)
if(expression)
# Commands
elseif(expression)
# Commands
else()
# Commands
endif()
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
message("Debug build")
endif()
add_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]
)
add_custom_command(
TARGET MyExecutable POST_BUILD
COMMAND ${CMAKE_COMMAND} -E echo "Build completed."
)
一个简单的 CMakeLists.txt 文件示例:
cmake_minimum_required(VERSION 3.10)
project(MyProject CXX)
# 添加源文件
add_executable(MyExecutable main.cpp)
# 设置 C++ 标准
set(CMAKE_CXX_STANDARD 11)
变量和缓存¶
CMake 使用变量来存储和传递信息,这些变量可以在 CMakeLists.txt 文件中定义和使用。
变量可以分为普通变量和缓存变量。
变量定义与使用¶
定义变量:
set(MY_VAR "Hello World")
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() 指令自动检测和配置外部库和包。
常用于查找系统安装的库或第三方库。
find_package() 指令¶
基本用法:
find_package(Boost REQUIRED)
find_package(Boost 1.70 REQUIRED)
find_package(OpenCV REQUIRED PATHS /path/to/opencv)
target_link_libraries(MyExecutable Boost::Boost)
include_directories(${Boost_INCLUDE_DIRS})
link_directories(${Boost_LIBRARY_DIRS})
使用第三方库¶
假设你想在项目中使用 Boost 库,CMakeLists.txt 文件可能如下所示:
cmake_minimum_required(VERSION 3.10)
project(MyProject CXX)
# 查找 Boost 库
find_package(Boost REQUIRED)
# 添加源文件
add_executable(MyExecutable main.cpp)
# 链接 Boost 库
target_link_libraries(MyExecutable Boost::Boost)
工作流程¶
- 编写 CMakeLists.txt 文件: 定义项目的构建规则和依赖关系。
- 生成构建文件: 使用 CMake 生成适合当前平台的构建系统文件(例如 Makefile、Visual Studio 工程文件)。
- 执行构建: 使用生成的构建系统文件(如 make、ninja、msbuild)来编译项目。

详细构建流程¶
CMake 的构建流程分为几个主要步骤,从设置项目到生成和执行构建命令。
- 创建构建目录:保持源代码目录整洁。
- 使用 CMake 生成构建文件:配置项目并生成适合平台的构建文件。
- 编译和构建:使用生成的构建文件执行编译和构建。
- 清理构建文件:删除中间文件和目标文件。
- 重新配置和构建:处理项目设置的更改。

以下是详细的构建流程说明:
1、创建构建目录
CMake 推荐使用 "Out-of-source" 构建方式,即将构建文件放在源代码目录之外的独立目录中。
这样可以保持源代码目录的整洁,并方便管理不同的构建配置。

创建构建目录:在项目的根目录下,创建一个新的构建目录。例如,可以创建一个名为 build 的目录。
mkdir build
cd build
2、使用 CMake 生成构建文件 在构建目录中运行 CMake,以生成适合当前平台的构建系统文件(例如 Makefile、Ninja 构建文件、Visual Studio 工程文件等)。
运行 CMake 配置:在构建目录中运行 CMake 命令,指定源代码目录。源代码目录是包含 CMakeLists.txt 文件的目录。
cmake ..
cmake -G "Ninja" ..
cmake -DCMAKE_BUILD_TYPE=Release ..
3、编译和构建 使用生成的构建文件进行编译和构建。
不同的构建系统使用不同的命令。
使用 Makefile(或类似构建系统):如果使用 Makefile,可以运行 make 命令来编译和构建项目。
make
make MyExecutable
ninja
ninja MyExecutable
也可以使用 msbuild 命令行工具来编译:
msbuild MyProject.sln /p:Configuration=Release
使用 Makefile:运行 make clean 命令(如果定义了清理规则)来删除生成的文件。
make clean
ninja clean
rm -rf build/*
5、重新配置和构建 如果修改了 CMakeLists.txt 文件或项目设置,可能需要重新配置和构建项目。
重新运行 CMake 配置:在构建目录中重新运行 CMake 配置命令。
cmake ..
make
CMake 构建实例¶
CMake 构建步骤如下:
- 创建 CMakeLists.txt 文件:定义项目、目标和依赖。
- 创建构建目录:保持源代码目录整洁。
- 配置项目:使用 CMake 生成构建系统文件。
- 编译项目:使用构建系统文件编译项目。
- 运行可执行文件:执行生成的程序。
- 清理构建文件:删除中间文件和目标文件。
假设我们有一个简单的 C++ 项目,包含一个主程序文件和一个库文件,我们将使用 CMake 构建这个项目。
我们的项目结构如下:
MyProject/
├── CMakeLists.txt
├── src/
│ ├── main.cpp
│ └── mylib.cpp
└── include/
└── mylib.h
- main.cpp:主程序源文件。
- mylib.cpp:库源文件。
- mylib.h:库头文件。
- CMakeLists.txt:CMake 配置文件。
创建 CMakeLists.txt 文件¶
在 MyProject 目录下创建 CMakeLists.txt 文件。
CMakeLists.txt 文件用于配置 CMake 项目。
CMakeLists.txt 文件内容:
cmake_minimum_required(VERSION 3.10) # 指定最低 CMake 版本
project(MyProject VERSION 1.0) # 定义项目名称和版本
# 设置 C++ 标准为 C++11
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)
- cmake_minimum_required(VERSION 3.10):指定 CMake 的最低版本为 3.10。
- project(MyProject VERSION 1.0):定义项目名称为 MyProject,版本为 1.0。
- set(CMAKE_CXX_STANDARD 11):指定 C++ 标准为 C++11。
- include_directories(${PROJECT_SOURCE_DIR}/include):指定头文件目录。
- add_library(MyLib src/mylib.cpp):创建一个名为 MyLib 的库,源文件是 mylib.cpp。
- add_executable(MyExecutable src/main.cpp):创建一个名为 MyExecutable 的可执行文件,源文件是 main.cpp。
- target_link_libraries(MyExecutable MyLib):将 MyLib 库链接到 MyExecutable 可执行文件。
创建构建目录¶
为了保持源代码目录的整洁,我们将在项目根目录下创建一个单独的构建目录。
创建构建目录
打开终端,进入 MyProject 目录,然后创建构建目录:
mkdir build
cd build
配置项目¶
在构建目录中使用 CMake 配置项目。
这将生成适合平台的构建系统文件(如 Makefile)。
运行 CMake 配置
在构建目录中运行 CMake 配置命令:
cmake ..
编译项目¶
使用生成的构建系统文件编译项目。根据生成的构建系统文件类型,使用相应的构建命令。
使用 Makefile
如果生成了 Makefile(在大多数类 Unix 系统中默认生成),可以使用 make 命令进行编译:
make
运行可执行文件¶
编译完成后,可以运行生成的可执行文件。
运行可执行文件
在构建目录中,运行 MyExecutable:
./MyExecutable
清理构建文件¶
清理构建文件以删除生成的中间文件和目标文件。
- 使用 make clean
如果在 CMakeLists.txt 中定义了清理规则,可以使用 make clean 命令:
make clean:删除中间文件和目标文件。make clean - 手动删除
如果没有定义清理规则,可以手动删除构建目录中的所有文件:
rm -rf build/*