用 Bear 生成 compile_commands.json 是为 Clangd 提供编译信息最直接的方式之一,尤其适合基于 make、cmake(非 Ninja)或自定义构建脚本的项目;需单独安装 Bear,用 bear -- 前缀包裹构建命令以拦截编译调用并生成标准 JSON 数据库。

用 Bear 生成 compile_commands.json 是为 Clangd 提供编译信息最直接的方式之一,尤其适合基于 make、cmake(非 Ninja)或自定义构建脚本的项目。关键在于让 Bear 拦截实际调用的编译命令,并汇总成标准 JSON 编译数据库。
确保 Bear 已安装并可用
Bear 是一个独立的工具,不是 Clang 或 CMake 自带组件。需单独安装:
-
macOS:用 Homebrew 安装:
brew install bear - Ubuntu/Debian:
sudo apt install bear - Arch Linux:
sudo pacman -S bear - 源码编译(如需最新版):从 GitHub 仓库 克隆并按文档构建
安装后运行 bear --version 验证是否就绪。
在构建前用 Bear 包裹构建命令
Bear 本身不解析 CMakeLists.txt 或 Makefile,而是通过 LD_PRELOAD 拦截子进程中的 gcc、g++、clang、clang++ 调用。因此必须用 bear -- 前缀启动你的构建流程:
立即学习“C++免费学习笔记(深入)”;
- 对纯 Make 项目:
bear -- make clean && bear -- make -j(注意:两次都要加bear --,clean 不产生编译命令,但后续 build 必须被拦截) - 对 CMake 项目(Unix Makefiles):
mkdir build && cd build && bear -- cmake .. && bear -- make -j - 若用 Ninja(CMake 默认),Bear 对 Ninja 支持不稳定,建议显式指定
-G "Unix Makefiles"再构建
成功执行后,当前目录(或指定输出路径)会生成 compile_commands.json,内容为每个源文件对应的完整编译命令数组。
验证与 Clangd 配合是否生效
Clangd 默认会在项目根目录查找 compile_commands.json。确认以下几点:
- 文件位于你打开的 VS Code 工作区根目录,或通过
clangd.fallbackFlags手动指定包含路径 - VS Code 中安装了官方 clangd 插件(非 C/C++ 插件),并在设置中启用
- 在 VS Code 的命令面板中运行
Clangd: Restart language server,观察输出通道是否提示 “Loaded compilation database” - 打开一个
.cpp文件,悬停函数或按Ctrl+Click应能跳转到定义,且无“no definition found”提示
常见问题与绕过技巧
如果 Bear 未生成文件或 Clangd 读取失败,可排查:
-
构建未真正触发编译:例如
make返回 “nothing to be done”,Bear 就不会记录任何命令。先make clean再bear -- make -
编译器路径未被拦截:Bear 默认只 hook 常见名称(gcc/g++/clang/clang++)。若项目用
arm-linux-gnueabihf-g++等交叉编译器,需用--append或改用intercept-build(Bear 3.0+ 新命令)并配合--override-compiler -
CMake + Ninja 项目:优先改用
cmake -G "Unix Makefiles";或直接用 CMake 3.19+ 内置导出:cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=ON ..,无需 Bear
不复杂但容易忽略:Bear 只捕获它看到的那一次构建过程,务必保证构建命令中确实调用了 C++ 编译器,且没有被缓存跳过。











