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 路徑。
- 在模組內部引入第三方庫。
- 安裝後直接執行程式,不依賴手寫指令碼。