马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
×
嵌入式 Linux 驱动开发,很多人最初都用 VSCode 加 C/C++ 插件加 Remote-SSH 的组合。这个组合在普通项目里够用,但一碰到内核源码就露短:头文件找不到、补全几乎失效、跳转跳不到定义处。原因不难理解——C/C++ 插件靠自己猜编译选项,而内核这种大型工程,编译选项和头文件路径散落在 Makefile 里,猜不准。换 clangd 配 compile_commands.json,问题就解了。
一、先搞定 compile_commands.json
clangd 需要一个 compile_commands.json 才能准确解析项目的编译选项和文件依赖。生成它的工具有两个:CMake 和 Bear。CMake 要新学一套语法,入门成本不低;Bear 是直接从编译命令"录"出这个文件,正好适合已经在用 Makefile 的老工程,所以这里选 Bear。
安装 Bear
sudo apt-get install bear
Bear 的两种用法
- 2.4.x 之前:在 build 命令前直接加 bear,例如
bear make。
- 2.4.x 之后:用
bear -- 隔开,例如 bear -- make。
在 Linux 源码目录下生成
bear -l /usr/lib/x86_64-linux-gnu/bear/libear.so make -j4
执行完,项目根目录会多出 compile_commands.json。
踩坑:ld.so 报找不到 libear.so
报错形如 ld.so: object '/usr/${LIB}/bear/libear.so' from LD_PRELOAD。常见原因是 Bear 版本较老(比如 2.3.11)时没有自动设置 LD_PRELOAD 环境变量。解决办法两条路:
- 先查真实路径:
find /usr -name libear.so,然后用 bear -l 实际路径/libear.so 指定;
- 或者在执行前手动导出:
export LD_PRELOAD=实际路径/libear.so 再跑 bear。
二、切换到交叉编译环境
嵌入式开发用的是交叉编译器,而 compile_commands.json 里记录的编译器是宿主机的 cc。不换过来会报类似 Unsupported option '-mabi=' for target 'x86_64-unknown-linux-gnu' 的错误。在 vim 里批量替换即可:
:%s/"cc"/"arm-buildroot-linux-gnueabihf-gcc"/g
三、安装 clangd
直接 sudo apt-get install clangd 有时会提示无法定位软件包,因为系统默认源里的 clangd 版本太老,连装法都不一样。更稳的做法是从 clangd 官方发布页下载对应架构的压缩包,把里面的 bin 和 lib 拷到系统的 /usr 目录下,然后 clangd --version 确认版本。
四、VSCode 里的配置
在 VSCode 的 settings.json 中加这样一段:
"clangd.arguments": [
"--background-index",
"--compile-commands-dir=/home/yz/workspace/kernel-driver/linux-xlnx-xlnx_rebase_v5.4_2020.2",
"-j=4",
"--query-driver=/usr/bin/gcc",
"--clang-tidy",
"--clang-tidy-checks=performance-*,bugprone-*",
"--all-scopes-completion",
"--completion-style=detailed",
"--header-insertion=iwyu",
"--pch-storage=disk"
],
"clangd.path": "/usr/bin/clangd",
"clangd.fallbackFlags": [
"-I/home/yz/workspace/kernel-driver/linux-xlnx-xlnx_rebase_v5.4_2020.2/include",
"-I/home/yz/workspace/kernel-driver/linux-xlnx-xlnx_rebase_v5.4_2020.2/arch/arm/include",
"-I/home/yz/workspace/kernel-driver/linux-xlnx-xlnx_rebase_v5.4_2020.2/arch/arm/include/generated/"
]
逐项看一眼就明白了:--background-index 让 clangd 后台按 compile_commands.json 分析文件;--compile-commands-dir 指这个文件所在目录;-j=4 是并行任务数;--query-driver 指定编译器白名单路径;--clang-tidy 与 --clang-tidy-checks 打开静态检查;--all-scopes-completion 做全局补全,会自动补头文件;--completion-style=detailed 让补全信息更详细;--header-insertion=iwyu 按 include-what-you-use 的方式自动补 include;--pch-storage=disk 把预编译头放磁盘。
clangd.fallbackFlags 是兜底项:当 clangd 无法从 compile_commands.json 拿到编译选项时用它。这里填的就是内核源码的头文件路径,缺了它会出现大量"头文件找不到"的红波浪线。
五、工程目录下的 .clangd
在工程根建一个 .clangd 文件:
CompileFlags:
Add:
- ["-I", "/usr/include"]
Remove:
- -fconserve-stack
- -fno-ipa-sra
- -fno-var-tracking-assignments
Add 里加 -I /usr/include,解决标准库头文件找不到的问题。
Remove 里删掉那几个编译开关,解决 clangd 不认这些 GCC 私有参数导致的报错。
六、收尾验证
配置完成后重开窗口,打开一个驱动 C 文件:头文件跳转能不能进去、结构体成员补全出不出来、警告里还有没有 "no such file" 这类报错。如果都正常,说明这套 VSCode 加 clangd 加 Remote-SSH 的嵌入式 Linux 开发环境已经跑通。
这套流程的核心其实只有一条:让编辑器知道真实编译条件。只要 compile_commands.json 准确、交叉编译器名字替换到位、头文件路径给全,clangd 的表现会比通用 C/C++ 插件稳定得多。
qidao123.com企服评测-应用市场 编辑提示
本文记录 VSCode 加 clangd 加 Remote-SSH 搭建嵌入式 Linux 开发环境的完整过程,涵盖 Bear 生成 compile_commands.json、LD_PRELOAD 报错的两种处理办法、交叉编译器替换、clangd 手工安装、settings.json 与 .clangd 关键参数的作用。文中路径为示例,请按实际工程目录与工具链名称调整;所有操作限于自有或已授权的开发机,勿将编译产物与源码外传。 |