利用 LSP 阅读 Linux 内核源码
LSP 介绍
语言服务器协议(LSP)是编辑器与语言智能服务间的标 准化接口,支持代码补全、跳转定义等功能,实现跨语言和工具的无缝兼容,提升开发效率,不同的编辑器和 IDE 通常都支持安装语言插件,而很多语言插件通常都基于 LSP 实现。
本文使用的 C/C++ 的 LSP 基于 clangd,依赖编译源码并生成 compile_commands.json
,这种方式严格模拟编译过程(如宏展开、条件编译),而像 VSCode 的 C/C++ Intellisense 扩展就不需要这么麻烦,直接就可以跳转,因为它做了头文件与宏定义的自动推断,跳转也基于语法解析而非完整的编译上下文,所以它使用起来更轻量便捷,但准确性不如编译内核并生成 compile_commands.json
的方式。
生成 compile_commands.json
Linux 内核源码主要是 C 语言,推荐使用 clangd 作为 LSP Server,clangd 需要一个 compile_commands.json
文件来索引项目文件,该文件通常由项目中提供的工具生成,生成过程会编译项目源码。
首先需要编译一下内核(使用 clang 作为编译器):
# 编译所有模块,避免部分代码无法跳转
make CC=clang allyesconfig
# 使用 clang 编译
make CC=clang -j $(nproc)
强烈建议在 Linux 机器上编译。笔者尝试过在 MacOS 上编译,但遇到各种报错,比如某些依赖的头文件找不到,或者编译工具版本不兼容等(make, clang, ld),没有全部解决,就不折腾了,直接在 Linux 上编译。
如果编译成功,执行以下命令生成 compile_commands.json
:
python3 ./scripts/clang-tools/gen_compile_commands.py
较低版本的内核(比如5.4),需使用低版本 clang,且使用
python3 ./scripts/gen_compile_commands.py
来生成compile_commands.json
(注意脚本路径不一样)。
编辑器或 IDE 安装支持 C/C++ 的 LSP 插件
接下来为你的编辑器或 IDE 安装支持 C/C++ 的 LSP 插件,我用的 Neovim,基于 LazyVim 配置,直接通过 :LazyExtras
启用 lang.clangd
扩展即可,如果使用其它编辑器或 IDE 可根据自身情况自行安装 LSP 插件。
开始阅读源码
如果你的编辑器或 IDE 本来就在这台编译内核源码的 Linux 机器上,那么就可以直接阅读源码了,打开源码文件后会自动索引,可实现代码跳转。
以下是效果: