CMake 教程

CMake 教程

CMake 是一个跨平台的构建系统生成工具,它通过 CMakeLists.txt 描述项目的构建规则,自动生成 Makefile、Visual Studio 工程、Ninja 等本地构建文件,被 C/C++ 项目广泛采用。

为什么用 CMake

  • 跨平台:同一份配置在 Linux/macOS/Windows 上构建
  • 多工具链:支持 Make、Ninja、VS、Xcode 等
  • 生态成熟:大量库(find_package)与 IDE(CLion/VSCode)集成
  • 高效:Ninja 生成器构建速度极快

最小示例

# CMakeLists.txt
cmake_minimum_required(VERSION 3.16)
project(HelloWorld C)

add_executable(hello main.c)
// main.c
#include <stdio.h>
int main() {
    printf("Hello, CMake!\n");
    return 0;
}
# 构建
mkdir build && cd build
cmake ..
make
./hello

本教程将从安装配置开始,逐步掌握 CMake 的核心构建流程与高级特性。

CMake 安装与配置

CMake 安装与配置

使用 CMake 前需要先安装它。不同平台安装方式各异。

Linux(Ubuntu/Debian)

sudo apt update
sudo apt install cmake cmake-curses-gui
cmake --version

macOS

# Homebrew
brew install cmake
# 或从 https://cmake.org/download/ 下载 .dmg

Windows

# 方式1:下载安装包(勾选"Add to PATH")
# 方式2:winget
winget install Kitware.CMake

验证安装

cmake --version
# 输出示例: cmake version 3.28.0

相关工具

  • ccmake:基于 curses 的图形化配置界面
  • cmake-gui:GUI 配置工具(Windows/macOS)
  • ctest:测试工具
  • cpack:打包工具

基本使用流程

# 源码目录与构建目录分离(推荐)
mkdir build && cd build
cmake ..              # 配置
cmake --build .       # 构建(等价 make)
cmake --install .     # 安装(可选)

安装完成后,可以开始编写你的第一个 CMake 项目。

CMake 基础

CMake 基础

掌握 CMakeLists.txt 的基本语法是使用 CMake 的第一步。

基本语法

# 注释
cmake_minimum_required(VERSION 3.16)   # 最低版本
project(MyProject C CXX)               # 项目名与语言

# 定义变量
set(SOURCES main.c utils.c)

# 生成可执行文件
add_executable(app ${SOURCES})

# 生成静态库
add_library(mylib STATIC lib.c)

# 链接库
target_link_libraries(app PRIVATE mylib)

# 添加编译选项
target_compile_options(app PRIVATE -Wall -O2)

# 添加头文件目录
target_include_directories(app PRIVATE include/)

变量与引用

set(VAR value)        # 定义
${VAR}                # 引用
message(STATUS "VAR=${VAR}")  # 打印

条件与循环

if(CMAKE_BUILD_TYPE STREQUAL "Debug")
  add_compile_definitions(DEBUG)
else()
  add_compile_definitions(NDEBUG)
endif()

foreach(src IN LISTS SOURCES)
  message(STATUS "source: ${src}")
endforeach()

常用变量

  • CMAKE_BUILD_TYPE:Debug/Release
  • CMAKE_CXX_STANDARD:C++ 标准(11/14/17/20)
  • CMAKE_C_FLAGS / CMAKE_CXX_FLAGS:编译选项
  • PROJECT_NAME / PROJECT_SOURCE_DIR / PROJECT_BINARY_DIR

CMake 构建流程

CMake 构建流程

CMake 的构建分为"配置 → 生成 → 构建 → 安装"四个阶段,理解流程有助于排查问题。

阶段一:配置(Configure)

cmake -S . -B build
# -S 源码目录, -B 构建目录(分离构建)

CMake 读取 CMakeLists.txt,检查依赖、编译器,生成构建系统文件(Makefile/Ninja 等)。

阶段二:生成(Generate)

配置阶段自动完成生成。可指定生成器:

cmake -S . -B build -G Ninja
cmake -S . -B build -G "Visual Studio 17 2022"

阶段三:构建(Build)

cmake --build build -j8            # 并行 8 线程
cmake --build build --config Release  # 多配置生成器指定配置

阶段四:安装(Install)

cmake --install build --prefix /usr/local

增量构建

再次执行 cmake --build build 只编译修改过的文件,CMake 自动处理依赖关系。

清理与重建

rm -rf build    # 删除构建目录完全重来(解决诡异问题)

缓存文件

build/CMakeCache.txt 保存配置结果,cmake-gui/ccmake 可交互修改缓存变量。

CMake 构建实例

CMake 构建实例

通过一个完整实例,演示从零构建一个带库和测试的 C 项目。

项目结构

demo/
├── CMakeLists.txt
├── include/math_utils.h
├── src/
│   ├── main.c
│   └── math_utils.c
└── tests/test_math.c

根 CMakeLists.txt

cmake_minimum_required(VERSION 3.16)
project(MathDemo C)

set(CMAKE_C_STANDARD 11)

# 数学库
add_library(math_utils STATIC
    src/math_utils.c)
target_include_directories(math_utils PUBLIC include)

# 可执行程序
add_executable(demo src/main.c)
target_link_libraries(demo PRIVATE math_utils)

# 测试
enable_testing()
add_executable(test_math tests/test_math.c)
target_link_libraries(test_math PRIVATE math_utils)
add_test(NAME math_test COMMAND test_math)

源码

// include/math_utils.h
int add(int a, int b);

// src/math_utils.c
int add(int a, int b) { return a + b; }

// src/main.c
#include <stdio.h>
#include "math_utils.h"
int main() {
    printf("1+2=%d\n", add(1, 2));
    return 0;
}

构建与测试

cmake -S . -B build
cmake --build build
./build/demo            # 输出 1+2=3
ctest --test-dir build  # 运行测试

CMake 高级特性

CMake 高级特性

进阶主题包括查找依赖库、选项控制、安装规则与导出目标等。

查找依赖(find_package)

# 查找 OpenSSL
find_package(OpenSSL REQUIRED)
target_link_libraries(app PRIVATE OpenSSL::SSL OpenSSL::Crypto)

# 查找其他库
find_package(Threads REQUIRED)
target_link_libraries(app PRIVATE Threads::Threads)

选项控制(option)

option(BUILD_TESTS "Build unit tests" ON)
if(BUILD_TESTS)
  enable_testing()
  add_subdirectory(tests)
endif()
# 配置时: cmake -S . -B build -DBUILD_TESTS=OFF

安装规则

install(TARGETS app RUNTIME DESTINATION bin)
install(TARGETS math_utils
        ARCHIVE DESTINATION lib
        LIBRARY DESTINATION lib)
install(FILES include/math_utils.h DESTINATION include)

编译特性控制

target_compile_features(app PRIVATE cxx_std_17)

FetchContent 拉取依赖

include(FetchContent)
FetchContent_Declare(json
  GIT_REPOSITORY https://github.com/nlohmann/json.git
  GIT_TAG v3.11.3)
FetchContent_MakeAvailable(json)

安装导出(package 配置)

通过 configure_package_config_file 与 export() 可把自己库提供给其他 CMake 项目 find_package。

CMake 实战练习

CMake 实战练习

通过练习巩固 CMake 技能,覆盖多目录、第三方库与发布构建等真实场景。

练习 1:多目录项目

project/
├── CMakeLists.txt
├── app/        (可执行程序)
├── libs/core/  (静态库)
└── libs/io/    (另一个库)

# 根 CMakeLists.txt
add_subdirectory(libs/core)
add_subdirectory(libs/io)
add_subdirectory(app)

练习 2:接入第三方库

# 使用 system 已装的库
find_package(PkgConfig REQUIRED)
pkg_check_modules(SDL2 REQUIRED sdl2)
target_link_libraries(app PRIVATE ${SDL2_LIBRARIES})
target_include_directories(app PRIVATE ${SDL2_INCLUDE_DIRS})

练习 3:多配置与发布

cmake -S . -B build/release   -DCMAKE_BUILD_TYPE=Release   -DCMAKE_INSTALL_PREFIX=/opt/myapp
cmake --build build/release -j
cmake --install build/release

# 打包(debian 包等)
cpack --config build/release/CPackConfig.cmake

练习 4:交叉编译(可选)

# 使用工具链文件
cmake -S . -B build-arm   -DCMAKE_TOOLCHAIN_FILE=arm-linux-gnueabihf.toolchain.cmake

完成这些练习后,你已经可以在真实项目中熟练使用 CMake 管理构建了。

CMake 官方教程与文档

CMake 官方教程与文档

CMake 官方提供了高质量的学习资源,是深入学习的首选。

官方教程

CMake 官方入门教程(Step 1-12)覆盖从基础到打包、测试、依赖管理的完整路径:https://cmake.org/cmake/help/latest/guide/tutorial/index.html

官方文档

  • CMake 命令参考:cmake-commands 手册,查阅所有命令
  • CMake 变量参考:cmake-variables,了解内置变量
  • CMake 模块:FindXXX.cmake 与实用模块列表
  • Policy 说明:版本升级行为变化

学习建议

  1. 先跑通官方 tutorial 前 6 步(基础)
  2. 再完成 7-12 步(安装、打包、测试、依赖)
  3. 遇到问题优先查官方文档,其次是 Stack Overflow

官方文档地址:https://cmake.org/documentation/

CMake 社区与源码

CMake 社区与源码

参与社区与阅读源码能帮助你更深入理解 CMake 的工作原理。

CMake 源码仓库

CMake 本身是开源项目,源码托管在 GitLab:https://gitlab.kitware.com/cmake/cmake,可以提交 issue、合并请求或参与开发。

社区资源

  • CMake 官方 Discourse:https://discourse.cmake.org 官方问答社区
  • Stack Overflow:cmake 标签,海量实践问答
  • Modern CMake:https://cliutils.gitlab.io/modern-cmake 经典现代 CMake 教程
  • awesome-cmake:GitHub 上 CMake 资源汇总

参与贡献

  • 报告 bug 与提交补丁
  • 编写/改进 FindXXX.cmake 模块
  • 参与讨论新特性(如 Package Manager 支持)
  • 翻译与本地化文档

延伸阅读

了解 Ninja 构建系统、ccache 缓存加速、conan/vcpkg 包管理器与 CMake 的配合,构建工具链会更加完整。

第 1 / 9 节