---
# System prepended metadata

title: 成功生成內核 compile_commands.json 的過程紀錄

---

# 成功生成內核 `compile_commands.json` 的過程紀錄

參考
https://www.reddit.com/r/neovim/comments/18lvsh3/problems_in_reading_linux_source_code_with_neovim/
 https://devmp.org/linux/kernel/2020/12/04/Linux-Kernel-Setup-Your-Editor.html
## 背景
在處理大型專案或內核開發時，`clangd` 等工具需要依賴 `compile_commands.json` 作為編譯資料庫，以正確解析代碼。但對於內核代碼這類專案，生成該文件的過程可能會較為複雜，特別是在使用 GCC 而非 Clang 的情況下。

以下記錄了一個成功生成 `compile_commands.json` 的完整過程，供日後參考。

---

## 步驟

### **1. 準備內核源碼**
確認內核源碼已正確下載並解壓：
```bash
cd /usr/src
tar -xvf linux-source-5.15.0.tar.bz2 -C ~/linux-source-5.15.0
```

將解壓後的目錄移動至合適的位置，例如：
```bash
mv ~/linux-source-5.15.0 ~/projects/linux-5.15
cd ~/projects/linux-5.15
```

---

### **2. 安裝內核標頭文件**
內核開發需要正確的標頭文件支持，進入內核源碼目錄後安裝內核標頭：
```bash
make headers_install INSTALL_HDR_PATH=./headers
```

這將標頭文件安裝到當前目錄下的 `./headers` 文件夾中，便於管理和引用。

---

### **3. 設置內核配置**
生成 `.config` 配置文件，可以選擇默認配置：
```bash
make defconfig
```
或使用互動界面進行自定義：
```bash
make menuconfig
```
確保完成後生成 `.config` 文件，這是後續步驟的基礎。

---

### **4. 構建腳本工具**
內核專案需要構建部分腳本工具以支持編譯過程：
```bash
make scripts
```

這一步會生成必要的工具，例如處理內核頭文件的腳本。

---

### **5. 生成 `compile_commands.json`**
使用內建的工具生成編譯資料庫：
```bash
make CC=gcc -j$(nproc)
python3 ./scripts/clang-tools/gen_compile_commands.py
```

> **注意：** 如果 `gen_compile_commands.py` 不存在，請確認內核版本支持該腳本，或手動下載對應版本。

完成後，檔案會生成在當前目錄：
```bash
ls compile_commands.json
```

---

### **6. 處理可能的格式問題**
檢查生成的 `compile_commands.json` 是否包含 GCC 特有的編譯標誌，這些標誌可能導致 `clangd` 無法解析。

#### **常見問題：**
- **未知標誌：** 如 `-mindirect-branch`、`-mfunction-return`。
- **解決方法：**
  - 使用正則表達式過濾這些標誌。
  - 自行編寫腳本清理文件。

例如，移除不支持的標誌：
```bash
jq 'map(.command |= sub("-mindirect-branch[^ ]* "; ""))' compile_commands.json > temp.json && mv temp.json compile_commands.json
```

---

## 結果
完成後，`compile_commands.json` 可用於支持 `clangd` 等工具進行內核代碼解析。

### 測試
在 `nvim` 中打開一個內核文件，測試 `clangd` 是否正常工作：
```bash
nvim drivers/gpu/drm/drm_edid.c
```
測試功能：
- 跳轉到定義（`gd`）。
- 懸停顯示文檔（`K`）。
- 查找引用（`gr`）。

---

## 經驗總結
- **配置的必要性：** `make defconfig` 或其他配置步驟是生成成功的基礎。
- **腳本工具的重要性：** 確保執行 `make scripts`，否則部分內核工具無法運作。
- **日誌清理：** 根據需求清理 `compile_commands.json` 中的無效標誌，提升工具兼容性。

---

## 適用場景
- 內核代碼調試。
- 大型專案的代碼分析。
- 配合 `clangd` 提升開發效率。

