配置Neovim LSP支持交叉编译环境下的Linux内核

Jan. 31, 2025

很长一段时间里我都在用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不识别的指令,在运行的时候就会报错。

使用直接生成的compile_commands.json

可以再创建一个.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已经能正确提供语法分析了:

函数提示