第 22.1 節

CMakePresets與構建安裝

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

CMakePresets.json 用來保存常用的 CMake 配置。它解決的問題是:不要每次都手寫一長串 cmake -S ... -B ... -G ... -D... 命令。

本模板的 CMakePresets.json 如下:

{
  "version": 6,
  "cmakeMinimumRequired": {
    "major": 3,
    "minor": 25,
    "patch": 0
  },
  "configurePresets": [
    {
      "name": "linux-debug",
      "displayName": "Linux Debug",
      "generator": "Ninja",
      "binaryDir": "${sourceDir}/build/linux-debug",
      "cacheVariables": {
        "CMAKE_BUILD_TYPE": "Debug",
        "CMAKE_EXPORT_COMPILE_COMMANDS": "ON",
        "CMAKE_INSTALL_PREFIX": "${sourceDir}/install/linux-debug"
      }
    },
    {
      "name": "linux-release",
      "displayName": "Linux Release",
      "generator": "Ninja",
      "binaryDir": "${sourceDir}/build/linux-release",
      "cacheVariables": {
        "CMAKE_BUILD_TYPE": "Release",
        "CMAKE_EXPORT_COMPILE_COMMANDS": "ON",
        "CMAKE_INSTALL_PREFIX": "${sourceDir}/install/linux-release"
      }
    }
  ],
  "buildPresets": [
    {
      "name": "linux-debug",
      "configurePreset": "linux-debug"
    },
    {
      "name": "linux-release",
      "configurePreset": "linux-release"
    }
  ]
}

根字段

version

"version": 6

表示 CMakePresets.json 文件格式版本,不是項目版本。

可以填什麼:

含義
123、...CMake preset 文件格式版本
6本模板使用的版本,適合 CMake 3.25 及以上

注意:

  1. 這裏不是 cmake_template 的版本號。
  2. 如果想兼容更老的 CMake,要降低 version,但某些字段可能不能再用。
  3. 如果本機 CMake 很新,也不一定要用最高 preset 版本;夠用即可。

cmakeMinimumRequired

"cmakeMinimumRequired": {
  "major": 3,
  "minor": 25,
  "patch": 0
}

表示讀取這個 preset 文件所需的最低 CMake 版本。

可以填什麼:

字段示例含義
major3主版本號
minor25次版本號
patch0補丁版本號

這個模板要求 CMake >= 3.25,是因為頂層 CMakeLists.txt 也寫了:

cmake_minimum_required(VERSION 3.25)

二者最好保持一致。

configurePresets

configurePresets 是"配置階段"的 preset。

配置階段對應命令:

cmake --preset linux-debug

它等價於告訴 CMake:

  1. 使用哪個生成器。
  2. 構建目錄在哪裏。
  3. 構建類型是什麼。
  4. 安裝目錄在哪裏。
  5. 是否生成 compile_commands.json

name

"name": "linux-debug"

preset 的機器可讀名稱。

可以填什麼:

寫法説明
linux-debug本模板 Debug preset
linux-release本模板 Release preset
debug也可以,但不如 linux-debug 清楚
gcc-debug如果區分編譯器,可以這樣命名
clang-debug如果添加 Clang preset,可以這樣命名

要求:

  1. 同一個數組裏不能重名。
  2. buildPresets 裏的 configurePreset 要引用這裏的名字。
  3. 命令行使用的就是這個名字。

示例:

cmake --preset linux-debug

displayName

"displayName": "Linux Debug"

給人看的名字,主要用於 IDE 顯示,例如 VSCode CMake Tools 的 preset 列表。

可以填什麼:

寫法説明
Linux Debug清晰
Linux Release清晰
Debug可以,但不區分平台
Fedora GCC Debug如果 preset 很多,可以寫更具體

這個字段不影響實際構建邏輯。

generator

"generator": "Ninja"

指定 CMake 要生成什麼構建系統文件。

Linux 常見可選值:

説明
Ninja推薦,速度快,輸出乾淨,適合 VSCode CMake Tools
Unix Makefiles傳統 Makefile 工作流
Ninja Multi-Config多配置 Ninja,可同時管理 Debug / Release

本模板只支持 Linux,並且使用 Ninja,所以固定寫:

"generator": "Ninja"

如果使用 Unix Makefiles,構建命令仍然可以用:

cmake --build --preset linux-debug

但底層就不是 Ninja 了。

binaryDir

"binaryDir": "${sourceDir}/build/linux-debug"

指定構建目錄。

可以填什麼:

寫法説明
${sourceDir}/build/linux-debug推薦,構建產物留在項目內的 build 子目錄
${sourceDir}/build/debug也可以,但不如 linux-debug 清楚
/tmp/my-build可以放到項目外,但不適合作為模板默認值

常見宏:

含義
${sourceDir}項目源碼根目錄
${presetName}當前 preset 名稱
${sourceParentDir}源碼根目錄的父目錄

也可以寫成:

"binaryDir": "${sourceDir}/build/${presetName}"

這樣 linux-debug 會自動生成到:

build/linux-debug

本模板顯式寫出目錄,是為了讓初學時更直觀。

cacheVariables

"cacheVariables": {
  "CMAKE_BUILD_TYPE": "Debug",
  "CMAKE_EXPORT_COMPILE_COMMANDS": "ON",
  "CMAKE_INSTALL_PREFIX": "${sourceDir}/install/linux-debug"
}

cacheVariables 等價於命令行中的 -D 參數。

例如:

"CMAKE_BUILD_TYPE": "Debug"

等價於:

-DCMAKE_BUILD_TYPE=Debug

常用 cache 變量

CMAKE_BUILD_TYPE

"CMAKE_BUILD_TYPE": "Debug"

單配置生成器中使用的構建類型。NinjaUnix Makefiles 都屬於常見的單配置生成器。

可以填什麼:

作用
Debug調試構建,通常帶 -g,優化較少
Release發佈構建,通常開啓優化
RelWithDebInfo優化 + 調試信息
MinSizeRel優化體積

常用選擇:

場景推薦
寫代碼、調試斷點Debug
發佈、性能測試Release
性能測試但還想保留符號RelWithDebInfo
嵌入式或體積敏感MinSizeRel

CMAKE_EXPORT_COMPILE_COMMANDS

"CMAKE_EXPORT_COMPILE_COMMANDS": "ON"

是否生成 compile_commands.json

可以填什麼:

作用
ON生成 compile_commands.json
OFF不生成

compile_commands.json 記錄每個源文件真實的編譯命令。clangd、VSCode、很多靜態分析工具都會用它來獲得 include 路徑、宏定義、編譯標準等信息。

建議模板裏固定開啓:

"CMAKE_EXPORT_COMPILE_COMMANDS": "ON"

讓 clangd 找到 compile_commands.json

僅僅生成 compile_commands.json,不代表 clangd 一定能自動找到它。

在 VSCode 中使用這種方式前,需要安裝 LLVM 官方的 clangd 擴展。 CMake Tools 負責配置、構建和選擇 target,clangd 則負責代碼補全、 跳轉定義、語義檢查等編輯功能,它們不是同一個擴展。

這個模板把 Debug 構建目錄設置為:

build/linux-debug/

因此執行:

cmake --preset linux-debug

之後,編譯數據庫位於:

build/linux-debug/compile_commands.json

clangd 默認會從當前源文件所在目錄逐級向上尋找 compile_commands.json。它通常能找到項目根目錄或 build/ 直屬目錄 中的數據庫,但不一定會繼續搜索 build/linux-debug/ 這樣的多層 preset 目錄。

如果 clangd 沒有找到數據庫,它會進入 fallback 模式,只用少量默認 參數分析源文件。這時即使 CMake 可以正常編譯,VSCode 中仍可能出現:

  1. 項目頭文件顯示找不到。
  2. Eigen、OpenCV 等第三方庫顯示找不到。
  3. C++ 標準識別錯誤,例如工程使用 C++23,clangd 卻按照 C++17 分析。
  4. 跳轉定義、自動補全和錯誤提示不準確。

推薦在項目根目錄創建 .clangd

CompileFlags:
  CompilationDatabase: build/linux-debug

目錄結構會變成:

.
├── .clangd
├── CMakeLists.txt
├── CMakePresets.json
├── build/
│   └── linux-debug/
│       └── compile_commands.json
└── src/

CompilationDatabase 使用相對於 .clangd 所在目錄的路徑,所以不要 寫某個用户電腦上的絕對路徑。這個文件只保存項目通用配置,可以提交到 Git。

注意,.clangd 不會生成編譯數據庫。第一次使用工程,或者修改了 CMakeLists.txt、編譯選項、依賴和 preset 後,仍然要重新執行:

cmake --preset linux-debug

或者在 VSCode CMake Tools 中選擇 linux-debug 並點擊 Configure。

如果 .clangd 創建後沒有立即生效,可以在 VSCode 命令面板執行:

clangd: Restart language server

也可以關閉並重新打開當前 .cpp 文件。

如果同時安裝了 Microsoft C/C++ 擴展,並且編輯器出現兩套重複的錯誤 提示,可以保留該擴展提供的 GDB 調試功能,同時關閉它的 IntelliSense, 讓 clangd 獨立負責代碼分析。這屬於個人 VSCode 設置,不需要寫入 CMake 模板。

檢查 clangd 是否真的生效

在 VSCode 中打開:

查看 -> 输出 -> clangd

正常情況下應當看到類似內容:

Loaded compilation database from .../build/linux-debug/compile_commands.json
Compile command from CDB is: ...

如果看到:

Failed to find compilation database
command clangd fallback

説明 clangd 仍然沒有讀到編譯數據庫。依次檢查:

  1. VSCode 打開的是否為項目根目錄。
  2. .clangd 是否位於項目根目錄。
  3. 是否已經執行過 cmake --preset linux-debug
  4. build/linux-debug/compile_commands.json 是否真實存在。
  5. .clangd 中的目錄名是否與 binaryDir 完全一致。

如果系統終端中可以直接使用 clangd,還可以檢查單個源文件:

clangd --check=src/main.cpp

輸出中應當顯示它加載了 build/linux-debug/compile_commands.json, 並使用 CMake 生成的 include 路徑、宏定義和 C++ 標準。

使用 Release 數據庫

如果希望 clangd 按照 Release 配置分析,可以改成:

CompileFlags:
  CompilationDatabase: build/linux-release

並先生成對應數據庫:

cmake --preset linux-release

日常開發通常使用 build/linux-debug 即可。不要同時讓 .clangd 指向 一個尚未生成或已經過期的構建目錄。

CMAKE_INSTALL_PREFIX

"CMAKE_INSTALL_PREFIX": "${sourceDir}/install/linux-debug"

指定安裝目錄。

可以填什麼:

寫法説明
${sourceDir}/install/linux-debug本模板 Debug 安裝目錄
${sourceDir}/install/linux-release本模板 Release 安裝目錄
/usr/local系統級安裝路徑,需要權限,不適合作為模板默認
/opt/my_project系統級或部署路徑

本模板把安裝目錄放在項目內,是為了方便學習和刪除。

安裝後運行:

./install/linux-debug/bin/cmake_template

buildPresets

buildPresets 是"構建階段"的 preset。

構建階段對應命令:

cmake --build --preset linux-debug

本模板寫法:

"buildPresets": [
  {
    "name": "linux-debug",
    "configurePreset": "linux-debug"
  },
  {
    "name": "linux-release",
    "configurePreset": "linux-release"
  }
]

name

"name": "linux-debug"

構建 preset 名稱。

一般建議和對應的 configure preset 同名,這樣命令比較一致:

cmake --preset linux-debug
cmake --build --preset linux-debug

configurePreset

"configurePreset": "linux-debug"

表示這個 build preset 使用哪個 configure preset 生成的構建目錄。

可以填什麼:

説明
linux-debug使用 Debug 構建目錄
linux-release使用 Release 構建目錄

必須對應 configurePresets 中已經存在的 name

常見可擴展字段

初學時可以先不用,但以後可能會見到。

description

給 preset 添加更長的説明。

"description": "Debug build for Linux using Ninja"

hidden

隱藏某個 preset,不直接給用户選擇,通常用於繼承。

"hidden": true

inherits

繼承另一個 preset,減少重複。

{
  "name": "linux-debug",
  "inherits": "linux-base",
  "cacheVariables": {
    "CMAKE_BUILD_TYPE": "Debug"
  }
}

environment

設置環境變量。

"environment": {
  "CC": "/usr/bin/gcc",
  "CXX": "/usr/bin/g++"
}

一般不建議模板默認寫死編譯器,除非你的項目明確要求某個工具鏈。

targets

指定默認構建哪些 target。

"targets": ["cmake_template"]

如果不寫,默認構建全部 target。

jobs

指定並行編譯數量。

"jobs": 8

不寫時由底層構建工具決定。

為什麼沒有 installPresets

很多人會猜測可以寫:

cmake --install --preset linux-debug

但常見 CMake preset 文件並不使用這個根字段。這個模板採用更通用的安裝命令:

cmake --install build/linux-debug

安裝命令需要傳入構建目錄,因為安裝規則是在 configure 階段生成到構建目錄裏的。

VSCode CMake Tools 工作流

安裝 VSCode 的 CMake Tools 擴展後,它會自動識別 CMakePresets.json

這一節把命令行操作和 VSCode 圖形界面操作對應起來。

打開 CMake 面板

用 VSCode 打開工程根目錄後,點擊左側邊欄的 CMake

如果 CMake Tools 正常識別工程,你會看到 preset、Configure、Build、運行 target 等入口。

Configure

命令行:

cmake --preset linux-debug

在 VSCode 圖形界面中,對應的是:

  1. 點擊 Configure。
  2. 選擇 Linux Debug

alt text

這一步會讀取:

CMakePresets.json
CMakeLists.txt

並生成:

build/linux-debug/

如果你改了 CMakeLists.txt、新增了源文件、修改了第三方依賴,通常需要重新 Configure。

Build

命令行:

cmake --build --preset linux-debug

在 VSCode 圖形界面中,CMake Tools 會在 Configure 後識別對應的 build preset。

alt text

然後點擊左下角或 CMake 面板裏的 Build 按鈕:

alt text

這一步會編譯 .cpp 文件,並生成 build 目錄裏的可執行文件和動態庫。

本模板的 Debug 可執行文件通常在:

build/linux-debug/src/cmake_template

如果你只是修改了普通 .cpp 代碼,一般只需要重新 Build,不一定要重新 Configure。

運行 build 目錄裏的程序

命令行:

./build/linux-debug/src/cmake_template

在 VSCode 圖形界面中,對應的是:

  1. 選擇運行/調試 target。
  2. 選擇 cmake_template
  3. 點擊運行按鈕。

alt text

alt text

運行後,終端裏會看到程序輸出。

alt text

如果你要斷點調試,就點擊 CMake Tools 提供的 Debug 按鈕;如果只是直接運行程序,就點擊 Launch 按鈕。

除了上面的操作入口,VSCode 底部狀態欄中,Build 按鈕旁邊也有 DebugLaunch 快捷按鈕。選擇好 cmake_template target 並完成構建後,可以直接點擊這裏運行或調試程序。

alt text

Install

命令行:

cmake --install build/linux-debug

在 VSCode 圖形界面中,可以按 Ctrl+Shift+P 打開命令面板,然後輸入:

CMake: Install

alt text

如果當前選擇的是 linux-debug preset,它等同於:

cmake --install build/linux-debug

安裝後的程序在:

install/linux-debug/bin/cmake_template

日常寫代碼、運行、調試,一般直接使用 build 目錄裏的程序:

build/linux-debug/src/cmake_template

只有在驗證安裝佈局、頭文件安裝、動態庫 RPATH 或準備發佈程序時,才需要 install。

對應關係總結

你想做的事命令行VSCode CMake Tools
配置工程cmake --preset linux-debug選擇 Linux Debug 後點擊 Configure
編譯工程cmake --build --preset linux-debug點擊 Build
運行 build 產物./build/linux-debug/src/cmake_template選擇 cmake_template target 後點擊運行按鈕
調試 build 產物用 GDB 調試 build/linux-debug/src/cmake_template選擇 cmake_template target 後點擊 Debug 按鈕
安裝工程cmake --install build/linux-debug命令面板執行 CMake: Install

這樣不需要手寫 .vscode/tasks.json,也不需要額外準備 VSCode 調試配置文件。

運行與調試注意事項

CMake Tools 可以直接運行或調試當前選擇的可執行 target,所以不需要手寫額外的運行腳本。

如果要調試,建議安裝 Microsoft C/C++ 擴展和 GDB,因為 CMake Tools 負責選擇 target,真正的 C/C++ 調試器仍然需要 GDB/LLDB 支持。

如果你只改了 .cpp 代碼,一般重新 Build 後再運行或調試即可。

如果你改了 CMakeLists.txt、新增源文件、改依賴,建議先 Configure,再 Build,然後再運行或調試。

為什麼不寫 tasks.json

舊模板常用 .vscode/tasks.json 寫一長串命令:

cmake ..
make install
source setup.bash
run app

這個模板不這樣做。原因是構建、運行和調試入口都可以交給 CMake Tools 管理,命令行流程則由 CMakePresets.json 固化。

這樣職責更清楚:

文件負責
CMakePresets.jsonconfigure/build 參數
VSCode CMake Tools選擇 preset、Configure、Build、運行和調試 target
CMakeLists.txttarget、依賴、安裝規則

需要安裝 gdb

Ubuntu/Debian:

sudo apt install gdb

Fedora:

sudo dnf install gdb

常見錯誤

忘記安裝 Ninja

報錯可能類似:

CMake was unable to find a build program corresponding to "Ninja"

解決:

sudo apt install ninja-build

或:

sudo dnf install ninja-build

preset 名稱寫錯

錯誤命令:

cmake --preset debug

如果文件裏沒有 debug 這個 preset,就會失敗。

查看可用 preset:

cmake --list-presets

build 前沒有 configure

如果第一次直接運行:

cmake --build --preset linux-debug

可能會因為構建目錄還沒有生成而失敗。

正確順序:

cmake --preset linux-debug
cmake --build --preset linux-debug
音乐页