clangd 找不到 compile_commands.json 时需手动生成或指定路径:用 CMake 启用 -DCMAKE_EXPORT_COMPILE_COMMANDS=ON 生成后软链至根目录,或手动编写合法 JSON;VS Code 中须禁用 C/C++ 扩展的 IntelliSense 引擎以避免冲突。

clangd 找不到 compile_commands.json 怎么办
clangd 默认只认项目根目录下的 compile_commands.json,不自动递归查找,也不读 CMakeLists.txt 或 Makefile —— 它不是构建系统,只是解析器。
常见错误现象:clangd 启动后提示 "No compilation database found",补全失效、跳转报错、头文件标红。
- 用 CMake 生成:在构建目录(如
build/)运行cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=ON ..,再把生成的compile_commands.json软链或复制到项目根目录 - 不用 CMake?手动写一个最简版也行(尤其单文件或小项目),内容结构必须合法 JSON,且
directory字段要写绝对路径 - VS Code 用户注意:
c_cpp_properties.json是 Microsoft C/C++ 扩展用的,clangd 完全不读它 —— 删掉或留着都行,但别指望它起作用
clangd 启动参数怎么选:–compile-commands-dir vs –query-driver
这两个参数解决的是不同层级的问题:前者定位编译命令,后者绕过系统默认限制去调用真实编译器。
使用场景:你用的是自定义工具链(比如交叉编译)、或系统里装了多个 GCC/Clang 版本,clangd 默认找不到 libstdc++ 头、报 "'vector' file not found"。
立即学习 “C++ 免费学习笔记(深入)”;
-
--compile-commands-dir=build/:告诉 clangd 到build/目录下找compile_commands.json,比软链更干净,适合 CI 或多构建配置项目 -
--query-driver=/usr/bin/clang++或--query-driver="/opt/my-toolchain/bin/*":让 clangd 主动调用指定编译器,提取其内置头路径和宏定义;通配符*必须加引号,否则 shell 展开会失败 - ⚠️ 注意:启用
--query-driver会显著拖慢首次索引速度,且某些 sandbox 环境(如 VS Code Remote-Containers)可能禁止执行任意二进制,此时会静默失败
VS Code 中 clangd 和 C/C++ 扩展能共存吗
能,但必须关掉其中一个的语言服务,否则会抢 textDocument/didOpen 请求,导致跳转错乱、诊断重复、hover 显示两遍。
常见错误现象:鼠标悬停显示两套类型信息;按 F12 跳转到系统头却进不去实现;修改代码后诊断延迟 5 秒以上。
- 如果你选 clangd,就在
settings.json加:"C_Cpp.intelliSenseEngine": "disabled",并确保"cppTools.enableConfigurationSquiggles": false - 不要同时启用
clangd.enabled和C_Cpp.autocomplete—— 前者是语言服务器开关,后者是旧版本地补全,混用等于双倍混乱 - 扩展推荐顺序:只装
clangd官方插件(llvm-vs-code-extensions.vscode-clangd),卸载ms-vscode.cpptools;后者功能虽多,但和 clangd 的协议层有隐式冲突,尤其在模板推导和 macro 展开上
头文件路径没生效?检查 .clangd 文件的 YAML 格式细节
.clangd 是 clangd 唯一认的项目级配置文件,但它对缩进、冒号空格、列表写法极其敏感 —— YAML 不是宽松格式。
典型错误:CompileFlags: 写成 CompileFlags :(冒号后多空格)、add: 下面的路径没顶格、用 Tab 缩进、忘记在路径字符串加引号(含空格时必炸)。
- 正确写法示例:
CompileFlags: Add: ["-I", "include", "-I", "/opt/mylib/include"] - 路径含空格?必须加双引号:
["-I", "/path/with space/include"],单引号也行,但不能不加 - 避免用
CompilationDatabasePath指向非标准位置 —— 它只接受相对项目根的路径,且不支持环境变量或~展开
最麻烦的点往往不在配置本身,而在 clangd 进程是否真的 reload 了 .clangd:改完后得重启编辑器或手动触发“Restart Language Server”,光保存文件没用。