第 22 節

CMake工程模板

0瀏覽次數0訪問次數--跳出率--平均停留

本章用一個 Linux-only 的 CMake 工程模板來講解 C++ 項目如何組織、構建、安裝和引入第三方庫。

這個模板的目標不是把 CMake 所有語法一次講完,而是圍繞一個真實可運行的工程,理解現代 CMake 最常用的一套寫法:

  1. 頂層 CMakeLists.txt 只做工程總控。
  2. CMakePresets.json 固化 Debug / Release 構建配置。
  3. cmake/ProjectOptions.cmake 保存項目公共編譯選項。
  4. src/CMakeLists.txt 管理主程序。
  5. 每個庫目錄自己管理源碼、頭文件、安裝規則和第三方依賴。
  6. 第三方庫採用"誰使用,誰 find_package"的方式。

模板目錄結構

模板的核心目錄如下:

.
├── CMakeLists.txt
├── CMakePresets.json
├── cmake/
│   └── ProjectOptions.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保存構建預設,例如 linux-debuglinux-release
cmake/ProjectOptions.cmake保存 C/C++ 標準、公共 warning 等配置
src/CMakeLists.txt創建最終可執行文件,並鏈接 lib1lib2
src/lib1/CMakeLists.txt創建 lib1_src_lib,管理 lib1 自己的 include、依賴、安裝
src/lib2/CMakeLists.txt創建 lib2_src_lib,管理 lib2 自己的 include、依賴、安裝

構建命令

這個模板使用 CMakePresets + Ninja。

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

這幾條命令分別做了四件事:

命令作用
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 更適合用來驗證"安裝後的目錄結構和動態庫路徑是否正確"。

configure、build、install 的區別

CMake 工程一般有三個階段:

configure

cmake --preset linux-debug

這個階段讀取所有 CMakeLists.txtCMakePresets.json,檢查編譯器、第三方庫、變量,並生成構建系統文件。

使用 Ninja 時,會在 build/linux-debug 下生成 build.ninja

build

cmake --build --preset linux-debug

這個階段調用 Ninja 編譯 .cpp 文件,生成 .o.so、可執行文件等構建產物。

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 自動選擇合適目錄。

為什麼不用手寫 build/install/log 腳本

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

  1. 自己創建 build 目錄。
  2. build 裏執行 cmake ..
  3. 手寫 make install
  4. 手寫腳本設置 LD_LIBRARY_PATH
  5. 自己維護日誌目錄。

這個模板改成 CMakePresets 後,這些內容都不再需要:

舊做法新做法
手動 cd buildCMakePresets.json 統一設置 binaryDir
手動設置 Debug / Releasepreset 裏設置 CMAKE_BUILD_TYPE
手動設置安裝路徑preset 裏設置 CMAKE_INSTALL_PREFIX
手動調用 Makefilepreset 指定 Ninja
手動設置動態庫路徑安裝目標設置 INSTALL_RPATH
手寫 VSCode taskVSCode CMake Tools 直接讀取 preset
手寫複雜調試腳本VSCode CMake Tools 直接運行或調試當前 CMake target

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 按鈕。

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

本章建議閲讀順序

  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. 安裝後直接運行程序,不依賴手寫腳本。
音乐页