Wiki
CMake工程模板
本章用一个支持 Linux 和 Windows 的 CMake 工程模板来讲解 C++ 项目如何组织、构建、安装和引入第三方库。
模板源码见 CMake_Template。当前最低要求为 CMake 3.22,CMakePresets.json 使用格式版本 3,默认 C++ 标准为 C++20。
Ubuntu 22.04 可以直接使用系统软件源提供的 CMake 3.22.1,准备好 Ninja、C++ 编译器和 Eigen 3 后即可构建,无需为本模板升级 CMake。在容器中开发时,这些工具应安装在容器内,供 VSCode CMake Tools 使用。
Linux 使用 GCC;Windows 使用 GCC / MinGW-w64,推荐 MSYS2 UCRT64。还没有准备环境时,先完成 C++开发环境搭建与测试 中自己系统的步骤,再来读本章。
这个模板的目标不是把 CMake 所有语法一次讲完,而是围绕一个真实可运行的工程,理解现代 CMake 最常用的一套写法:
- 顶层
CMakeLists.txt只做工程总控。 CMakePresets.json固化 Debug / Release 构建配置。cmake/ProjectOptions.cmake保存项目公共编译选项。src/CMakeLists.txt管理主程序。- 每个库目录自己管理源码、头文件、安装规则和第三方依赖。
- 第三方库采用"谁使用,谁
find_package"的方式。
1.模板目录结构
模板的核心目录如下:
.
├── CMakeLists.txt
├── CMakePresets.json
├── cmake/
│ ├── ProjectOptions.cmake
│ └── WindowsRuntime.cmake
└── src/
├── CMakeLists.txt
├── main.cpp
├── lib1/
│ ├── CMakeLists.txt
│ ├── inc/
│ │ └── lib1/
│ │ └── eigen3_test.hpp
│ └── src/
│ └── eigen3_test.cpp
└── lib2/
├── CMakeLists.txt
├── inc/
│ └── lib2/
│ └── eigen3_test.hpp
└── src/
└── eigen3_test.cpp
其中:
| 文件 | 职责 |
|---|---|
CMakeLists.txt |
顶层入口,声明项目、加载公共配置、进入 src |
CMakePresets.json |
保存两种平台的 Debug / Release 构建和测试预设 |
cmake/ProjectOptions.cmake |
保存 C/C++ 标准、公共 warning 等配置 |
cmake/WindowsRuntime.cmake |
安装 MinGW 工具链中找到的常用 GCC 运行库 |
src/CMakeLists.txt |
创建最终可执行文件,并链接 lib1、lib2 |
src/lib1/CMakeLists.txt |
创建 lib1_src_lib,管理 lib1 自己的 include、依赖、安装 |
src/lib2/CMakeLists.txt |
创建 lib2_src_lib,管理 lib2 自己的 include、依赖、安装 |
2.构建命令
这个模板使用 CMakePresets + Ninja。下面先按 Linux 展示流程,再给出 Windows 对应命令。两种系统的 configure、build 和 install 原理相同。
Debug 构建:
cmake --preset linux-debug
cmake --build --preset linux-debug
cmake --install build/linux-debug
./install/linux-debug/bin/cmake_template
Release 构建:
cmake --preset linux-release
cmake --build --preset linux-release
cmake --install build/linux-release
./install/linux-release/bin/cmake_template
Windows,PowerShell 中的 Debug 构建:
cmake --preset windows-debug
cmake --build --preset windows-debug
cmake --install build/windows-debug
./install/windows-debug/bin/cmake_template.exe
Release 将 windows-debug 改为 windows-release。日常开发直接运行 ./build/windows-debug/bin/cmake_template.exe 即可。
这几条命令分别做了四件事:
| 命令 | 作用 |
|---|---|
cmake --preset linux-debug |
配置工程,生成 Ninja 构建文件 |
cmake --build --preset linux-debug |
编译源码并链接目标 |
cmake --install build/linux-debug |
把可执行文件、库、头文件安装到 install/linux-debug |
./install/linux-debug/bin/cmake_template |
运行安装后的程序 |
日常开发时,不需要每次都安装。编译后可以直接运行 build 目录里的程序:
./build/linux-debug/src/cmake_template
install 更适合用来验证"安装后的目录结构和动态库路径是否正确"。
模板保留了 GitHub Actions 中 Linux 和 Windows UCRT64 的 Debug / Release 检查。Windows 检查会移除 PATH 中的开发工具链,再运行整体移动后的安装目录。新增第三方库后,还要补齐自己的依赖和测试。
3.configure、build、install 的区别
CMake 工程一般有三个阶段:
3.1.configure
cmake --preset linux-debug
这个阶段读取所有 CMakeLists.txt 和 CMakePresets.json,检查编译器、第三方库、变量,并生成构建系统文件。
使用 Ninja 时,会在 build/linux-debug 下生成 build.ninja。
3.2.build
cmake --build --preset linux-debug
这个阶段调用 Ninja 编译 .cpp 文件,生成 .o、.so、可执行文件等构建产物。
3.3.install
cmake --install build/linux-debug
这个阶段按照 install(...) 规则,把构建产物复制到安装目录。
在本模板中,Debug 安装到:
install/linux-debug/
Release 安装到:
install/linux-release/
安装后的典型结构如下:
install/linux-debug/
├── bin/
│ └── cmake_template
├── include/
│ ├── lib1/
│ │ └── eigen3_test.hpp
│ └── lib2/
│ └── eigen3_test.hpp
└── lib64/
├── liblib1_src_lib.so
└── liblib2_src_lib.so
有些 Linux 发行版会使用 lib,有些会使用 lib64。本模板通过 GNUInstallDirs 让 CMake 自动选择合适目录。
Windows 预设使用静态项目库,安装目录的主要结构为:
install/windows-debug/
├── bin/
│ ├── cmake_template.exe
│ └── 常用 GCC 运行库文件
├── include/
│ ├── lib1/eigen3_test.hpp
│ └── lib2/eigen3_test.hpp
└── lib/
├── liblib1_src_lib.a
└── liblib2_src_lib.a
两种平台使用同一份头文件和源文件,库类型由各自的预设选择,后面会逐项解释。
4.为什么不用手写 build/install/log 脚本
旧式模板里常见这种做法:
- 自己创建
build目录。 - 在
build里执行cmake ..。 - 手写
make install。 - 手写脚本设置
LD_LIBRARY_PATH。 - 自己维护日志目录。
这个模板改成 CMakePresets 后,这些内容都不再需要:
| 旧做法 | 新做法 |
|---|---|
手动 cd build |
CMakePresets.json 统一设置 binaryDir |
| 手动设置 Debug / Release | preset 里设置 CMAKE_BUILD_TYPE |
| 手动设置安装路径 | preset 里设置 CMAKE_INSTALL_PREFIX |
| 手动调用 Makefile | preset 指定 Ninja |
| 手动设置动态库路径 | Linux 设置 INSTALL_RPATH;Windows 静态链接项目库,并安装常用 GCC 运行库 |
| 手写 VSCode task | VSCode CMake Tools 直接读取 preset |
| 手写复杂调试脚本 | VSCode CMake Tools 直接运行或调试当前 CMake target |
5.VSCode CMake Tools 运行与调试
这个模板不需要额外写 VSCode 调试配置。安装 CMake Tools 后,VSCode 可以直接识别 CMake 里的可执行 target,并对当前 target 执行运行或调试。
图形化流程可以理解成命令行流程的按钮版本:
| 命令行 | VSCode CMake Tools |
|---|---|
cmake --preset linux-debug |
选择 Linux Debug preset 后 Configure |
cmake --build --preset linux-debug |
点击 Build |
./build/linux-debug/src/cmake_template |
选择 cmake_template target 后点击运行按钮 |
| 用 GDB 调试 build 目录产物 | 选择 cmake_template target 后点击 Debug 按钮 |
CMake Tools 运行或调试的通常是 build 目录里的可执行文件:
build/linux-debug/src/cmake_template
因此日常开发不需要每次 install。install 主要用于验证安装布局、头文件安装、动态库 RPATH 等内容。
推荐流程:
- 安装 VSCode CMake Tools 扩展和 Microsoft C/C++ 扩展。
- 选择
linux-debugconfigure preset。 - Configure。
- Build。
- 选择
cmake_template作为运行/调试 target。 - 点击 CMake Tools 提供的运行按钮或 Debug 按钮。
Windows 选择 windows-debug,运行路径对应 build/windows-debug/bin/cmake_template.exe;GDB 要使用 Windows 工具链中的 gdb.exe。界面按钮的含义相同。
更详细的图形界面操作步骤见 CMakePresets与构建安装。
6.本章建议阅读顺序
- CMakePresets与构建安装:先理解 preset 工作流。
- 顶层CMake与公共编译选项:理解顶层入口和公共配置。
- src与lib模块CMake详解:理解可执行文件、库、include、install。
- 第三方库依赖写法:学习 Eigen、OpenCV、Boost、PCL 等库如何引入。
学完后,你应该能做到:
- 新建一个 C++ 工程并用 preset 构建。
- 添加新的库目录。
- 添加新的可执行文件。
- 正确管理头文件 include 路径。
- 在模块内部引入第三方库。
- 安装后直接运行程序,不依赖手写脚本。