基于Clangd索引Linux内核源代码,提供跳转和补全
适用于Neovim、Vim、VSCode等支持LSP的编辑器。
1 操作示例
1.1 操作环境
操作系统:Ubuntu 20.04 in wsl2
编辑器:VSCode
LSP:Clangd
内核版本:longterm 5.15.145
1.2 准备工作
由于gcc
和clang
并非完全兼容,使用gcc
编译后生成的compile_commands.json
中可能包含clangd
无法识别的Unknown argument
,导致clangd
索引出现报错。故采用clang
作为编译器。
由于编译该版本的Linux内核需要clang
的最小版本为10.0.1
,默认从仓库中安装的版本为10.0.0
,不满足最小版本需求。因此需要执行如下命令安装更新版本的clang-12
和clangd-12
。
$ sudo apt install clang-12 clangd-12
注意:
clang
和clangd
的版本需要对应。否则最后代码提示可能也会报Unknown argument
错误。
1.3 编译Linux内核并生成compile_commands.json
- 从官网下载Linux内核源代码
- 使用命令
$ tar xvf linux-5.15.145.tar.xz
解压源代码 - 进入解压后的源代码目录。
- 配置编译
$ make CC=clang-12 defconfig # 由于默认的clang链接到了clang-10,不满足版本要求,故此处需要指定clang-12
- 执行编译
$ make CC=clang-12 -j16
- 生成
compile_commands.json
$ python ./scripts/clang-tools/gen_compile_commands.py
1.4 编辑VSCode配置
- 用VSCode打开Linux内核源码文件夹
- 安装
clangd
插件 - 禁用
C/C++
插件的代码提示,在Workspace的settings.json
中添加如下代码:"C_Cpp.intelliSenseEngine": "disabled",
- 设置
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",
- 重启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'?
......
原因:
- 使用
gcc
编译,而gcc
的某些编译选项clangd
不支持。需要改用clang
进行编译,或者在项目文件夹的.clangd
配置文件中禁用这些不支持的编译选项。参考clangd文档。 - 使用
clang
编译,但clang
的版本和提供代码提示的clangd
版本不对应,不同版本间clangd
支持的编译选项也有差异。需要在VSCode等编辑器配置文件中指定和clang
版本对应的clangd
路径。