跳到正文

Wiki

CMake工程模板

約 9 分鐘閱讀

本文由簡體中文內容確定性轉換,並受版本化術語表保護。

本章用一個支援 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 最常用的一套寫法:

  1. 頂層 CMakeLists.txt 只做工程總控。
  2. CMakePresets.json 固化 Debug / Release 構建配置。
  3. cmake/ProjectOptions.cmake 儲存專案公共編譯選項。
  4. src/CMakeLists.txt 管理主程式。
  5. 每個庫目錄自己管理原始碼、標頭檔案、安裝規則和第三方依賴。
  6. 第三方庫採用"誰使用,誰 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 指令碼

舊式模板裡常見這種做法:

  1. 自己建立 build 目錄。
  2. 在 build 裡執行 cmake ..。
  3. 手寫 make install。
  4. 手寫指令碼設定 LD_LIBRARY_PATH。
  5. 自己維護日誌目錄。

這個模板改成 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 等內容。

推薦流程:

  1. 安裝 VSCode CMake Tools 擴充套件和 Microsoft C/C++ 擴充套件。
  2. 選擇 linux-debug configure preset。
  3. Configure。
  4. Build。
  5. 選擇 cmake_template 作為執行/除錯 target。
  6. 點選 CMake Tools 提供的執行按鈕或 Debug 按鈕。

Windows 選擇 windows-debug,執行路徑對應 build/windows-debug/bin/cmake_template.exe;GDB 要使用 Windows 工具鏈中的 gdb.exe。介面按鈕的含義相同。

更詳細的圖形介面操作步驟見 CMakePresets與構建安裝。

6.本章建議閱讀順序

  1. CMakePresets與構建安裝:先理解 preset 工作流。
  2. 頂層CMake與公共編譯選項:理解頂層入口和公共配置。
  3. src與lib模組CMake詳解:理解執行檔、庫、include、install。
  4. 第三方庫依賴寫法:學習 Eigen、OpenCV、Boost、PCL 等庫如何引入。

學完後,你應該能做到:

  1. 新建一個 C++ 工程並用 preset 構建。
  2. 新增新的庫目錄。
  3. 新增新的執行檔。
  4. 正確管理標頭檔案 include 路徑。
  5. 在模組內部引入第三方庫。
  6. 安裝後直接執行程式,不依賴手寫指令碼。