Wiki
CMake Project Template
Existing English translations were reused. 13 current source blocks remain in Simplified Chinese, without triggering paid translation.
本章用一个支持 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++开发环境搭建与测试 中自己系统的步骤,再来读本章。
The goal of this template is not to cover all CMake syntax at once, but rather to understand the most commonly used set of modern CMake practices around a real, runnable project:
- Top level
CMakeLists.txtis only responsible for overall project control. CMakePresets.jsonSolidify Debug / Release build configurations.cmake/ProjectOptions.cmakeSave the project's common compilation options.src/CMakeLists.txtManage the main program.- Each library directory manages its own source code, header files, installation rules, and third-party dependencies.
- Third-party libraries adopt the "whoever uses it, whoever
find_package" approach.
1.Template directory structure
The core directory of the template is as follows:
.
├── 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
Among them:
| 文件 | 职责 |
|---|---|
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.Build command
这个模板使用 CMakePresets + Ninja。下面先按 Linux 展示流程,再给出 Windows 对应命令。两种系统的 configure、build 和 install 原理相同。
Debug build:
cmake --preset linux-debug
cmake --build --preset linux-debug
cmake --install build/linux-debug
./install/linux-debug/bin/cmake_template
Release build:
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 即可。
These commands each perform four things:
| Command | Effect |
|---|---|
cmake --preset linux-debug |
Configure the project and generate Ninja build files |
cmake --build --preset linux-debug |
Compile the source code and link the target |
cmake --install build/linux-debug |
Install the executable files, libraries, and header files to install/linux-debug |
./install/linux-debug/bin/cmake_template |
Run the installed program |
During daily development, there is no need to install it every time. After compilation, you can directly run the program in the build directory:
./build/linux-debug/src/cmake_template
install It is more suitable for verifying "whether the installed directory structure and dynamic library paths are correct".
模板保留了 GitHub Actions 中 Linux 和 Windows UCRT64 的 Debug / Release 检查。Windows 检查会移除 PATH 中的开发工具链,再运行整体移动后的安装目录。新增第三方库后,还要补齐自己的依赖和测试。
3.Differences between configure, build, and install
A CMake project generally has three stages:
3.1.configure
cmake --preset linux-debug
At this stage, all CMakeLists.txt and CMakePresets.json are read, the compiler, third-party libraries, and variables are checked, and build system files are generated.
When using Ninja, it generates under build/linux-debug build.ninja.
3.2.build
cmake --build --preset linux-debug
This stage invokes Ninja to compile the .cpp files, generating build artifacts such as .o , .so , and executable files.
3.3.install
cmake --install build/linux-debug
In this phase, according to the install(...) rules, copy the build artifacts to the installation directory.
In this template, Debug is installed to:
install/linux-debug/
Release installed to:
install/linux-release/
The typical structure after installation is as follows:
install/linux-debug/
├── bin/
│ └── cmake_template
├── include/
│ ├── lib1/
│ │ └── eigen3_test.hpp
│ └── lib2/
│ └── eigen3_test.hpp
└── lib64/
├── liblib1_src_lib.so
└── liblib2_src_lib.so
Some Linux distributions use lib, while others use lib64. This template uses GNUInstallDirs to let CMake automatically select the appropriate directory.
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.Why not write scripts by hand build/install/log
This approach is commonly seen in old-style templates:
- Create your own
builddirectory. - In
build, runcmake ... - Handwrite
make install. - A handwritten script sets
LD_LIBRARY_PATH. - Maintain the log directory yourself.
After this template is changed to CMakePresets, none of these contents are needed anymore:
| 旧做法 | 新做法 |
|---|---|
手动 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 Running and Debugging
This template does not require writing an additional VSCode debug configuration. After installing CMake Tools, VSCode can directly recognize the executable targets in CMake and run or debug the current target.
A graphical process can be understood as the button version of a command-line process:
| Command line | VSCode CMake Tools |
|---|---|
cmake --preset linux-debug |
After selecting the Linux Debug preset, Configure |
cmake --build --preset linux-debug |
Click Build |
./build/linux-debug/src/cmake_template |
Select the cmake_template target then click the run button |
| Debug the build directory artifact with GDB | Select the cmake_template target then click the Debug button |
CMake Tools typically runs or debugs the executable files in the build directory:
build/linux-debug/src/cmake_template
Therefore, daily development does not require installation every time.install Mainly used to verify the installation layout, header file installation, dynamic library RPATH, and other such content.
Recommended process:
- 安装 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。界面按钮的含义相同。
For more detailed GUI operation steps, see CMakePresets and Build Installation.
6.Suggested Reading Order for This Chapter
- CMakePresets and Build Installation:First understand the preset workflow.
- Top-level CMake and Common Compilation Options:Understand the top-level entry and common configuration.
- Detailed Explanation of CMake for src and lib Modules:Understand executables, libraries, include, and install.
- How to Write Third-Party Library Dependencies:Learn how to introduce libraries such as Eigen, OpenCV, Boost, and PCL.
After completing this, you should be able to:
- Create a new C++ project and build it with a preset.
- Add a new library directory.
- Add a new executable.
- Correctly manage header file include paths.
- Introduce third-party libraries within a module.
- Run the program directly after installation, without relying on handwritten scripts.