vscode/vim+clangd 环境中实现正确索引交叉编译链中系统头文件路径
(本文假定读者已经对VSCode、LSP、clangd等相关知识有所了解,如果读者对相关内容尚未熟悉,建议先学习VSCode+LSP原理,再学习clangd插件的完整用法,clangd插件官方指导网站网站为:https://clangd.llvm.org,强烈建议认真完整的学习该网站的所有内容!)
自从谷歌创造了V8引擎(演化出node.js,他是VSCode和coc.nvim插件的基础),微软创造了VSCode和LSP协议,苹果创造了clang和clangd,C/C++编辑器领域就发生了翻天覆地的变化,先是VSCode + Remote-SSH + clangd插件通过LSP和clangd语言服务器实现了先进的 “语法级” 跳转 + 补全 + 高亮 + 语法静态解析 + 源码格式化体验,后是vim世界通过移植VSCode源码实现重量级的coc.nvim插件(从此vim几乎可以和VSCode实现同步进化)。目前几乎所有的编辑器都在利用LSP生态在快速的打造全新的功能特性。个人通过一段时间学习和配置,目前发现这套环境用来查看Linux内核源码简直是神一般的存在。
clangd之所以可以完美的匹配Linux内核项目主要原因是内核的Makefile维护的非常好的同时内核本身是一个完全自包含的项目,它对外界的依赖非常小(几乎所有的功能和函数库都在项目内部实现),因此只要产生正确的compile_commands.json就几乎可以实现100%准确的跳转等能力。
不过除了内核,日常工作中接触更多的还是业务层相关的项目,作为一个嵌入式从业人员,99%的时间在和交叉编译链打交道。clangd配合PC环境的GCC项目基本上不怎么需要配置就可以表现的比较完美了,但什么事情到了混乱的嵌入式领导都变得更加折腾,clangd也不例外。clangd用于交叉编译项目的时候一个明显的问题就是在默认配置下由于clangd不知道交叉编译链的位置, 因此也无法准确的知道编译器自带的系统头文件位置,此时默认的动作是将/usr/include等GCC默认系统头文件路径作为搜索路径,带来问题有两个:一是源码文件中include的.h文件跳转不准确,二是由于系统头文件的定义差异,导致源码中很多地方的变量等定义都可能解析失败,最终导致在稍微复杂点的项目中局部变量定义都可能跳转异常,这谁能忍!
目前解决该问题最简单的方法是通过给clangd传递–query-driver 启动参数来通知clangd交叉编译器的位置,clangd在启动时会利用传递的交叉便器参数自动解析出交叉编译链中所有系统头文件的路径(解析原理稍后分析)并自动玩过编译惨数的修改。
VScode中实现项目级–query-driver参数的传递可以通过在项目根目录的 “.vscode/settings.json” 文件添加实现,配置类似如下:
{
"clangd.arguments": [
"--all-scopes-completion",
"--completion-style=detailed",
"--query-driver=/home/boddy/t7linux-auto/ext-toolchain/bin/arm-linux-gnueabi*"