很长一段时间里我都在用VSCode和C/C++插件编写Linux的内核模块,使用起来也没有什么问题,但是时间一长,插件就会逐渐积累几个GB甚至几十个GB的缓存文件,而且插件运行时还会占据大量内存和CPU资源。为了节约内存,我迁移到了Vim,之后又改到了Neovim。
Neovim支持使用LSP(Language Server Protocol)提供语法解析,实现函数跳转、补全等等功能,只要所使用的语言有相应的Language Server实现就可以。
clangd就是一个基于clang的支持C/C++的language server。
为了让clangd能够理解你的C/C++工程,需要通过compile_commands.json
文件将工程的编译指令传递给clangd,文件内保存了编译工程里每个C/C++文件的编译指令(https://clang.llvm.org/docs/JSONCompilationDatabase.html)。
对于Linux下的make工程,可以用bear工具来生成compile_commands.json
。linux源码的scripts/clang-tools/gen_compile_commands.py
可以生成用于Linux内核的compile_commands.json
。
这里以一个内核模块的工程为例。首先使用bear生成make工程的compile_commands.json
:
make clean
bear -- make
因为clang和一些交叉编译链(比如aarch64-linux-gnu-gcc
)并不是完全兼容的,从以上命令生成的compile_commands.json
可能有clangd不识别的指令,在运行的时候就会报错。
可以再创建一个.clangd
文件,这是提供给clangd的配置,让clangd去掉不识别的指令,这样不需要修改compile_commands.json
(这个文件的定位就是自动生成出来的,可能是一个很庞大的文件)
比如移除-fconserve-stack
, -fno-allow-store-data-races
, -mabi=lp64
这三个导致报错的指令。
CompileFlags:
Remove: [-fconserve-stack, -fno-allow-store-data-races, -mabi=lp64]
.clangd
文件的其他配置参考:https://clangd.llvm.org/config
重启LSP(LspRestart
),可以看到clangd已经能正确提供语法分析了: