CMake 系列教程(一):CMake 基础知识

CMake 系列教程(一):CMake 基础知识

跨平台构建的艺术,从认识 CMake 开始


一、什么是 CMake?

CMake 是一个跨平台的开源构建系统生成器 (Build System Generator)。它并不直接编译代码,而是根据你编写的 CMakeLists.txt 配置文件,生成对应平台的原生构建文件:

平台 生成的构建文件
Linux / macOS Makefile、Ninja
Windows Visual Studio .sln / .vcxproj
通用 Ninja、NMake

简单理解:CMake 是构建系统的"元工具",它让你写一次配置,到处构建。


二、为什么选择 CMake?

2.1 跨平台是刚需

现实项目中,开发者可能用 Windows + MSVC 开发,而 CI 跑在 Linux + GCC 上。如果你手写 Makefile,Windows 上无法直接使用;如果写 .sln,Linux 上更没法用。CMake 一份配置,两处运行。

2.2 业界主流

  • 大型项目:LLVM、OpenCV、Boost、Qt、Vulkan、Google Test......
  • 集成友好:VSCode CMake Tools、CLion、Visual Studio 原生支持 CMake
  • 包管理:vcpkg、Conan 等包管理器都与 CMake 深度集成

2.3 对比其他方案

方案 跨平台 学习曲线 生态
手写 Makefile ❌ Linux/macOS 为主
Visual Studio 工程 ❌ Windows 专属 Windows
QMake ✅ 但绑定 Qt Qt
Bazel Google 系
CMake 最广泛

三、安装 CMake

3.1 Windows

powershell 复制代码
# 方式一:winget(推荐)
winget install Kitware.CMake

# 方式二:Chocolatey
choco install cmake

# 方式三:官网下载安装包
# https://cmake.org/download/

安装后确认:

powershell 复制代码
cmake --version
# cmake version 3.28.3

💡 提示 :Windows 安装时勾选 "Add CMake to the system PATH for all users" ,否则命令行找不到 cmake

3.2 Linux

bash 复制代码
# Ubuntu / Debian
sudo apt install cmake

# Fedora
sudo dnf install cmake

# 如果需要最新版,使用 Kitware 官方源
# https://apt.kitware.com/

3.3 macOS

bash 复制代码
# Homebrew
brew install cmake

四、核心概念

在动手写代码之前,先理解 CMake 的几个核心概念。

4.1 构建目录(Out-of-Source Build)

CMake 强烈推荐不在源码目录中构建 ,而是创建一个独立的 build/ 目录:

复制代码
my_project/
├── CMakeLists.txt      # 配置文件
├── src/
│   └── main.cpp        # 源码
└── build/              # 构建目录(可随时删除重建)
    ├── Makefile        # 生成的构建文件
    └── ...

好处 :构建产物不会污染源码目录,rm -rf build/ 即可彻底清理。

4.2 两步流程

CMake 的工作分为两步:

复制代码
┌─────────────┐     ┌─────────────┐
│  配置阶段    │ ──→ │  构建阶段    │
│  (Configure) │     │  (Build)    │
│             │     │             │
│ cmake -B    │     │ cmake --build│
│ CMakeLists  │     │ 调用编译器    │
│ → 生成构建文件│     │ → 生成目标文件│
└─────────────┘     └─────────────┘
  • 配置阶段 :读取 CMakeLists.txt,检测编译器、查找依赖,生成原生构建文件
  • 构建阶段 :调用底层构建工具(make、ninja、msbuild)编译代码

4.3 目标(Target)

Target 是 CMake 的核心抽象,有两种类型:

  • 可执行目标 (Executable):生成可运行程序,如 add_executable(myapp main.cpp)
  • 库目标 (Library):生成静态库/动态库,如 add_library(mylib STATIC lib.cpp)

现代 CMake(3.x)提倡以目标为中心的写法,而非传统的"目录级变量"风格。

4.4 生成器(Generator)

生成器决定 CMake 产出什么构建文件:

bash 复制代码
# 查看所有可用生成器
cmake --help

# 常用生成器
cmake -G "Unix Makefiles" ..    # Linux/macOS 默认
cmake -G "Ninja" ..             # 跨平台,速度最快
cmake -G "Visual Studio 17 2022" ..  # Windows

🚀 推荐 :优先使用 Ninja 生成器,比 Make 快很多,且跨平台。

bash 复制代码
# 安装 Ninja
# Ubuntu: sudo apt install ninja-build
# macOS:  brew install ninja
# Windows: winget install Ninja-build.Ninja

五、第一个 CMake 项目

5.1 项目结构

复制代码
hello_cmake/
├── CMakeLists.txt
└── main.cpp

5.2 源码

main.cpp

cpp 复制代码
#include <iostream>

int main() {
    std::cout << "Hello, CMake!" << std::endl;
    return 0;
}

CMakeLists.txt

cmake 复制代码
# 1. 最低版本要求
cmake_minimum_required(VERSION 3.20)

# 2. 项目定义
project(HelloCMake LANGUAGES CXX)

# 3. 添加可执行目标
add_executable(hello main.cpp)

三行配置,清晰明了:

作用
cmake_minimum_required 声明所需最低 CMake 版本,低于此版本会报错
project 定义项目名称和使用的语言(CXX = C++)
add_executable 告诉 CMake 编译 main.cpp 生成可执行文件 hello

5.3 构建与运行

bash 复制代码
# 配置 + 构建(一步到位写法,CMake 3.20+)
cmake -B build
cmake --build build

# 运行
./build/hello        # Linux/macOS
.\build\Debug\hello.exe  # Windows (Visual Studio)

💡 -B build 指定构建目录为 build/,无需手动 mkdir build && cd build


六、CMake 版本选择策略

不同 CMake 版本差异较大,选择策略如下:

场景 推荐最低版本 原因
个人新项目 3.25+ 享受最新特性(CMakePresets、FetchContent 改进)
团队项目 3.20+ 平衡新特性与兼容性
开源库 3.14+ 覆盖更广泛的用户环境

不要随意设太低 (如 VERSION 2.8),旧版本的行为与现代 CMake 差异巨大,容易踩坑。


七、常见问题

Q1:CMake 和 Make 是什么关系?

CMake 生成 Makefile,Make 执行 Makefile。 CMake 是"元构建系统",Make 是"构建系统"。关系如下:

复制代码
CMakeLists.txt → [CMake] → Makefile → [Make] → 可执行文件

Q2:修改了 CMakeLists.txt 后需要重新配置吗?

需要。 但如果你使用 cmake --build,它会自动检测并重新运行配置。如果直接用 make,则需要手动重新 cmake

Q3:构建出错如何彻底清理?

bash 复制代码
# 删除构建目录,重新来过
rm -rf build/
cmake -B build

这是 out-of-source build 最大的好处------删除 build/ 就回到初始状态。


小结

要点 内容
CMake 是什么 跨平台构建系统生成器
核心流程 配置(cmake -B)→ 构建(cmake --build)
核心抽象 Target(可执行/库)
最佳实践 Out-of-source build、使用现代 CMake 写法
生成器推荐 Ninja > Makefile

📖 下一期预告 :《CMake 系列教程(二):基础命令详解》------ 深入讲解 add_librarytarget_link_librariestarget_include_directories 等核心命令,掌握多文件、多目标的真实项目构建。

相关推荐
郝学胜_神的一滴9 小时前
CMake 034:生成器表达式:解耦构建时序、精简分支逻辑的终极利器
c++·cmake
见过夏天1 天前
C++ 基础入门完全指南
c++
用户805533698032 天前
不止三件套:QObject 属性系统全关键字与运行时反射!
c++·qt
BadBadBad__AK3 天前
线段树维护区间 k 次方和
c++·数学·算法·stl
卷无止境3 天前
Eigen 库如何借助 OpenMP 加速计算
c++·后端
卷无止境3 天前
OpenMPI、MPICH 与 OpenMP:关系、核心概念与架构全解
c++·后端
郝学胜_神的一滴4 天前
CMake 30:循环语法全解|foreach_while双循环精讲、迭代技巧与实战避坑指南
c++·cmake
卷无止境6 天前
C++ 的Eigen 库全解析
c++
卷无止境6 天前
现代 C++特性大盘点:一门脱胎换骨的老语言
c++·后端
郝学胜_神的一滴6 天前
CMake 27:缓存变量的特性、语法、类型与实操全解
c++·cmake