前言

本人之前阅读linux源代码有两种常见方式。其一是通过source insight新建linux内核代码工程, 不得不说source insight在阅读代码方面的交互确实很友好,但是在代码跳转精度方面还是稍显不足,很多代码甚至无法跳转。第二种方法就是利用vscode里面的c++插件,代码跳转精度有所提升,配合其他优化插件可以获得美观的阅读界面,然而这个插件动不动把CPU给占满,占用的空间和内存都很大,因此阅读体验也不是很好。

阅读linux内核源码,尤其是阅读跟CPU架构相关或者驱动相关的源码时,经常会遇到大量重复定义的函数需要手动排除以及函数指针无法定位相关函数的问题,导致以上两种方法在阅读源码时稍显吃力。偶然间发现vscode配合clangd可以较好的解决该问题,同时提供了很好的函数分析功能,clangd在占用资源方面相较于c++插件也很有优势,几乎不怎么占用CPU。研究过后完成了阅读环境的搭建,在此记录一下。

本人利用ssh远程服务器进行开发,vscode+ssh远程开发环境搭建教程很多,此处略过。以下介绍如何搭建阅读源码环境。

安装vscode

应该没人不会吧,略过。。。

安装clangd插件

在vscode插件市场上搜索并安装clangd插件,如下:

Vscode+Clangd 阅读linux内核源码_clangd

安装好插件以后,如果网络环境允许会自动下载安装clangd程序(clangd language server),如果下载失败可手动下载程序后放在某个目录,并在插件配置Path中指定clangd程序的路径即可。同时可以对clangd插件进行一些参数配置,配置如下:

Vscode+Clangd 阅读linux内核源码_vscode_02

安装bear

clangd的解析函数功能依赖于compile_commands.json文件,该文件不是手写的,而是可以通过bear工具在编译内核时自动生成。对于ubuntu,可用如下命令进行安装。

sudo apt download bear

如果服务器开发环境无法联网或者没有安装权限,可以尝试在其它电脑下载该软件包后再放到服务器上。实现步骤如下:

sudo apt download bear  #下载bear包
dpkg -x xxxx.deb ./ #对安装包进行解压
可执行程序在:./usr/bin #找到对应的可执行程序bear
动态库在:./usr/lib/x86_64-linux-gnu/bear/libear.so #该程序运行依赖于该动态库,可在执行时手动指定,也可以放到默认路径
执行bear:bear --libear=xxxxx/libar.so <cmd> #利用bear生成compile_commands.json文件

bear安装好以后就可以生成compile_commands.json文件了,命令是:

bear <编译内核的make指令>
e.g: bear make uImage -j20 ARCH=arm CROSS_COMPILE=arm-linux-gnueabi-

创建.clangd文件

以上环境搭建好后,还需最后一步,在vscode打开的源代码的根目录创建一个名为.clangd的文件,区分32位arm和64位arm,其内容如下:

32位:
CompileFlags:
Add: --target=armv7-a
64位:
CompileFlags:
Add: --target=aarch64-linux-gnu
Remove: -mabi=lp64

触发解析

如果clangd正常工作,在vscode打开源代码并且随便点击一个c文件后会开始解析项目,在工作路径下生成.cache文件夹,.cache文件夹下有当前每个被编译进去的文件对应的index;如果index文件数量太少(通常在800以上),几乎可以断定工作不正常,此时需要看vscode的解析状态来进一步分析原因。最终效果如下:可以进行函数跳转,过滤掉了没有被编译的函数,同时在分析函数指针时也少了很多干扰。

Vscode+Clangd 阅读linux内核源码_linux_03

需要注意的是,如果文件改动了,clangd在启动的时候会自动重新同步并生成新的index,但是如果新增了文件的话就需要重新执行bear make去生成新compile_commands.json,这样新的文件才会被索引。