Clangd 與編譯資料庫

最後更新: 2026-03-11 03:34:10 +0800 +0800
原文以英文撰寫。您正在閱讀AI翻譯版本。

clangd 會使用虛擬編譯器命令剖析每個開啟的檔案,以提供 C 與 C++ 語言伺服器功能。只有當該命令代表實際建置情境時,完成、診斷、導覽與重構才可靠;建置情境包括工作目錄、編譯器驅動程式、目標、語言模式、包含路徑、前處理器定義與產生的標頭檔。

提供編譯命令 #

編譯資料庫是首選的真實來源。compile_commands.json 為每個翻譯單元包含一個命令與工作目錄。CMake 可以為建置樹輸出它:

bash
cmake -S . -B build -DCMAKE_EXPORT_COMPILE_COMMANDS=ON
clangd --compile-commands-dir=build
json
[
  {
    "directory": "/work/project",
    "file": "src/main.cc",
    "command": "clang++ -Iinclude -std=c++20 -c src/main.cc"
  }
]

沒有 --compile-commands-dir 時,clangd 會從開啟檔案的目錄向上搜尋父目錄,尋找 compile_commands.json 或 compile_flags.txt。compile_flags.txt 是較簡單的後備方式:它對每個檔案提供每行一個旗標,無法表達不同翻譯單元具有不同旗標的目標。

text
-Iinclude
-std=c++20
-Wall

從權威建置產生資料庫,然後讓工作區可找到它。從儲存庫根目錄建立符號連結、設定編輯器,或使用 --compile-commands-dir 都有效;複製資料庫可能造成命令過時。對於沒有原生支援的建置系統,可以使用 Bear 等工具觀察乾淨建置,但產生的命令仍必須描述開發者開啟的設定。

標頭檔、新檔案與旗標調整 #

建置系統不會直接編譯標頭檔。對於標頭檔,clangd 會先重用包含它的已開啟來源檔命令;否則會選取檔名相似的資料庫項目。在多平台樹中,該啟發式方法可能選錯目標。請先開啟包含檔案的來源、讓標頭檔命名與其主要來源一致,或使用專案設定使預期情境明確。

不在資料庫中的檔案會收到後備命令。後備命令允許剖析,但沒有建置提供的目標專屬包含路徑、巨集、產生的標頭檔或語言模式。請將其診斷視為暫定結果,並在編輯新目標前將來源加入建置或提供設定。

.clangd 可以在不複製資料庫的情況下調整命令:

yaml
CompileFlags:
  Add: [-Ithird_party/api, -DMY_EDITOR_BUILD=1]
  Remove: [-Werror]

請將調整用於僅編輯器需要的修正,或 clangd 無法使用的旗標,而不要手動重建建置命令。只要可能,就保留編譯器可執行檔,因為其位置與名稱會影響預設標準函式庫查找與語言選取。

診斷錯誤情境 #

執行單一檔案檢查並檢查選取的命令:

bash
clangd --check=src/main.cc --log=verbose

詳細記錄會識別編譯資料庫、工作目錄與調整後的命令。找不到標頭檔時,請將 -I、-isystem、sysroot 與產生標頭檔路徑同實際編譯呼叫比較。剖析使用錯誤方言時,請確認 -x、-std=、Objective-C 與 C++ 的區別,以及編譯器驅動程式。內建項目或 ABI 相依型別不同時,請檢查 --target、工具鏈路徑與 SDK 旗標。

變更建置選項、相依性或產生來源後,重新產生資料庫。確保程式碼產生器在 clangd 讀取其輸出前執行,或提供產生的包含目錄與已提交的介面標頭檔。以額外的 clangd 旗標 啟動 LSP 伺服器,與變更檔案的編譯命令不同;若要改變來源語意,請使用後者。

評論

在 GitHub 上閱讀或評論(發表評論需要登入)