使用VSCode实现Electron及ffmpeg等超大项目代码智能感知

背景

最近一直使用VSCode来读代码和写代码,包括一些小的C项目和C++项目,用起来很顺手。

随着项目逐渐深入,我需要更有效率的在各种大型代码库中进行定义跳转及引用查找,并且需要精确的根据项目配置选择宏定义,另外就是在修改代码时对于使用到的数据结构进行代码提示。这里面包含了大量的使用到了GNU Make系列组织的项目以及Google系列的用ninja编译工具的项目。针对这两种项目,现在使用VSCode不能满足跨文件的智能感知,这个问题是否能解决呢。

历史

先回顾一下历史,之前智能感知是如何实现的

VS项目 & CMake项目: 风生水起

针对工作中自己写的代码,基本都是使用CLion来创建简单的CMake项目,然后在项目中可以简单的查找代码引用,定义跳转及自动实现代码提示。与此类似的还有使用Visual Studio读项目。

非IDE支持型项目: 刀耕火种

但是针对非IDE支持的项目,就比较费劲了。曾经为了修一个boringssl库和ReactNative共用导致boringssljemalloc的弱符号被ReactNative中的空实现强符号所覆盖导致执行崩溃的问题,一直追踪使用Makefile的boringssl库,当时尽管用了Understand这类的工具,但是遍地的结构体中的函数指针以及难以查看的定义以及引用,大大增加了理解和排查难度。

后来因工作需要理解并修改ElectronWebrtc部分音频同步代码,当时完全是用Google的在线代码阅读工具,一边根据代码库中的文件名猜测代码可能在的范围,一遍进去找到关键词,再使用全局搜索工具找定义和引用,虽然麻烦但是也能顺利理解和阅读代码。

非IDE支持型项目: 局部优化

在要修改ffmpeg的movencflvdec的代码时,我开始使用VSCode的自带C/C++插件,基本能做到大部分能做到当前文件内跳转。虽然跨文件基本不能用,但通过项目内文本搜索也能实现,已经相对很方便了。因为ffmpeg的结构比较合理,理解流程后所有修改基本都在同一个切面文件中修改即可。

搜索

通过一番搜索,发现了可以在.vscode目录中配置一下c_cpp_properties.json,配置好includePath即可实现所用到的头文件中库的定义跳转。还有就是可以标注上所需的宏定义,这样就能自动选择条件编译的分支。另外包含目录中所有本地的文件后,基本也可以做到跨文件跳转。样例如下

但是这样只能解决一些小项目,如果是大项目,有大量的依赖和文件,我不太可能一条一条全把定义等标注下来,有什么好办法么?

经过一番搜索后还真有所发现。VSCode提供了另一种机制,也就是可以将所有编译的命令导出成json, 并指定到c_cpp_properties.json中即可实现更智能的感知功能。而且经过搜索直接就发现了ninja自带导出编译命令compile_commands.json的功能。我在Electron的项目中能执行了下面的命令

这样就导出了编译命令集。下一步就是导入到VSCode中。修改c_cpp_properties.json

接下来重新打开VSCode的workspace,发现右下角不仅有了表示使用tag进行parse的圆柱图标,也 出现了使用编译命令进行parse的火苗图标。

然后试了下引用查找和定义跳转,无比顺利~

GNU Make的项目是否有办法呢? 经过搜索还真有。有一个工具叫做compiledb, 用一下方式安装

然后在ffmpeg的Makefile所在目录执行以下命令

这样既生成了compile_commands.json又生成了正常编译的目标文件
接下来重启了下VSCode,尝试跳转,又快又准!

到这里不得不赞叹一句:

微软,人类的希望~