这里记录一下我是如何在VSCode上使用clang帮助进行代码跳转、补全和检查的。
VSCode默认的C/C++插件在处理巨大的项目的时候好像非常占CPU。我后来就转到了clang。
VSCode插件
删除原始的C/C++插件并且安装clangd插件。
系统clangd工具安装
在系统上需要安装clangd、clang-format和clang-tidy。在ubuntu上就使用apt install就可以了。需要注意的是好像有时候安装的是clangd-xx(xx是版本号,12,14这样的数字)。最好在安装好之后就在clangd-xx对应的目录下建一个链接文件clangd指向这个clangd-xx。我的例子:
ln -sf /usr/bin/clangd-14 /usr/bin/clangd
ln -sf /usr/bin/clang-format-14 /usr/bin/clang-format
ln -sf /usr/bin/clang-tidy-14 /usr/bin/clang-tidy
生成compile_commands.json
clang工具是根据compile_commands.json文件中包含的项目中每个文件的编译命令来进行解析的。所以我们首先需要生成这个compile_commands.json文件。我们的项目是用的普通的make命令来编译的。所以需要用一个叫bear的工具来生成compile_commands.json文件。
安装使用Bear
我们需要在编译环境中使用bear。基本上来说就是bear会拦截编译过程中的命令来得知每个文件的编译参数并存储在compile_commands.json文件中。
- 我们首先需要安装bear,最方便的做法当然是使用apt-get。执行sudo apt install bear来安装bear。
- 如果不方便用apt-get。我们可以手动下载bear的deb文件并使用sudo dpkg -i 命令来安装。
- 如果还是没法安装可以使用sudo dpkg-deb -x命令把deb文件解压缩然后拷贝文件到目录中使用。真正起作用的文件只有两个,可执行程序bear和库文件libear-xxx.so。(这个是比较老版本的bear,新的bear是更加复杂了一些。)
你可以到这里下载一些旧版本的bear ==> Index of /ubuntu/pool/universe/b/bear/
我在Docker ubuntu 16.04中使用的是bear-2.3.11-1版本。在Docker中,如果gcc命令是32-bit但是系统是64-bit的会出现下面的错误信息。
所以我们需要手动安装32-bit的libear.so到/usr/lib32/bear/目录。至此,bear工具安装完毕!下面我们就可以使用他了。我们当然希望bear能够把所有文件的编译参数都记录下来,所以请执行make clean来清除所有编译信息。然后在原本的编译命令前加上bear,例如bear make。
经过一段时间编译完成后,在当前目录会有一个原始版本的compile_commands.json文件生成。上面的compile_commands.json文件有可能不在vscode打开的项目的根目录,我一般都是把文件再拷贝到VSCode workspace的根目录去。
compile_commands.json文件只要最开始生成一次就可以了。后面除非文件增加或者编译参数改变才会需要重新生成。
修改compile_commands.json
下面所说的修改都是因为我们的编译环境在Docker中才需要进行的步骤。如果你是本地编译的。可以跳过。
修改目录
打开这个文件你会发现其中一些目录信息是docker中的,但是我们的vscode运行在宿主机上,我们需要把这些目录信息修改为对应的宿主机上的目录信息。
当然了,最好在docker mount的时候把工作目录mount路径弄得和宿主机一样。这样就不需要修改了。
在宿主机和Docker里面目录结构不一致的情况下,我们需要把宿主机的目录结构信息传递到Docker中(因为脚本是在Docker中执行的)。我一般就是在执行Docker的脚步中增加一个把目录信息保存到文件中的语句。后面在Docker中执行的时候读取这个文件就知道宿主机的根目录信息了。
当你知道了Docker和宿主机上的目录对应关系后就可以很容易的用sed之类的工具进行修改了。
修改编译参数
另外,有可能宿主机上并没有交叉编译器,有一些编译参数也是宿主机上的cc命令所不支持的。对于这些参数,我们可以直接从compile_commands.json文件中删除。
或者在VSCode Workspace的根目录生成一个.clangd文件并在其中添加Remove compileFlags信息把这些参数从clangd解析的时候去掉。这两种方法都可以,我比较喜欢用修改.clangd文件的方法。
如何知道要去除哪些编译参数
打开vscode后可以看到下方有出现indexing:xxx/yyyy这样的字样,前面的小圆圈也在转。这就代表clangd正在对文件进行index。
你也可以通过查看clangd的OUTPUT信息查看clangd的工作情况。如果出现E[xx:xx:xx.xxx]开头的行,大概就是说明有错。这个时候你可以通过修改clangd插件的clangd参数,增加--log=verbose来获取更多的信息。很多情况下都是compile_commands.json里面的编译参数在外面不认。
clangd的index文件在Workspace根目录下的.cache/clangd/index目录。在修改了.clangd文件之后你也可以把.cache目录删除然后再打开vscode重新生成index并检查clangd的log文件看看还有没有什么需要修改的。
至此,clangd就可以正确的解析代码中的代码文件了。在看代码的时候如果可以正确的跳转还是非常惬意的。
版权归原作者 何穆 所有, 如有侵权,请联系我们删除。