基于Clangd索引Linux内核源代码,提供和补全

发布时间 2024-01-10 16:13:16作者: yann-qu

基于Clangd索引Linux内核源代码,提供和补全

适用于Neovim、Vim、VSCode等支持LSP的编辑器。

1 操作示例

1.1 操作环境

操作系统:Ubuntu 20.04 in wsl2
编辑器:VSCode
LSP:Clangd
内核版本:longterm 5.15.145

1.2 准备工作

由于gccclang并非完全兼容,使用gcc编译后生成的compile_commands.json中可能包含clangd无法识别的Unknown argument,导致clangd索引出现报错。故采用clang作为编译器。

由于编译该版本的Linux内核需要clang的最小版本为10.0.1,默认从仓库中安装的版本为10.0.0,不满足最小版本需求。因此需要执行如下命令安装更新版本的clang-12clangd-12

$ sudo apt install clang-12 clangd-12

注意:
clangclangd的版本需要对应。否则最后代码提示可能也会报Unknown argument错误。

1.3 编译Linux内核并生成compile_commands.json

  1. 官网下载Linux内核源代码
  2. 使用命令$ tar xvf linux-5.15.145.tar.xz解压源代码
  3. 进入解压后的源代码目录。
  4. 配置编译
    $ make CC=clang-12 defconfig # 由于默认的clang链接到了clang-10,不满足版本要求,故此处需要指定clang-12
    
  5. 执行编译
    $ make CC=clang-12 -j16
    
  6. 生成compile_commands.json
    $ python ./scripts/clang-tools/gen_compile_commands.py
    

1.4 编辑VSCode配置

  1. 用VSCode打开Linux内核源码文件夹
  2. 安装clangd插件
  3. 禁用C/C++插件的代码提示,在Workspace的settings.json中添加如下代码:
    "C_Cpp.intelliSenseEngine": "disabled",
    
  4. 设置clangd的路径。默认clangd的路径设置为clangd,表明VSCode会直接从环境变量中寻找可执行文件clangd。但由于默认的clangd链接到了clangd-10,我们编译内核使用的是clang-12,需要与其版本对应的clangd-12提供代码提示。因此这里需要根据你使用的clang版本设置与其对应的clangd可执行文件路径。由于笔者使用了clang-12,故需要在此使用clangd-12。在Workspace的settings.json中添加如下代码:
    "clangd.path": "clangd-12",
    
  5. 重启VSCode,加载插件和配置,发现能够正常完成源码索引,且没有报错。

2 常见问题

Unknown argument: '-fno-stack-clash-protection'
Unknown warning option '-Wno-frame-address'; did you mean '-Wno-address'?
Unknown warning option '-Wno-pointer-to-enum-cast'; did you mean '-Wno-pointer-compare'?
Unknown warning option '-Wno-frame-address'; did you mean '-Wno-address'?
Unknown warning option '-Wno-pointer-to-enum-cast'; did you mean '-Wno-pointer-compare'?
......

原因:

  1. 使用gcc编译,而gcc的某些编译选项clangd不支持。需要改用clang进行编译,或者在项目文件夹的.clangd配置文件中禁用这些不支持的编译选项。参考clangd文档
  2. 使用clang编译,但clang的版本和提供代码提示的clangd版本不对应,不同版本间clangd支持的编译选项也有差异。需要在VSCode等编辑器配置文件中指定和clang版本对应的clangd路径。