clangd 是当前唯一推荐的 c/c++ 语言服务器,因 ccls 已于 2023 年停止维护,存在崩溃、跳转失败、高 cpu 占用及对 c++20 等新特性支持滞后等问题;clangd 由 llvm 官方维护,lsp 实现成熟,支持异步后台索引,且被 vs code、clion、neovim 等主流工具默认集成。

ccls 已基本被弃用,当前应优先选 clangd;ccls 在 2023 年后停止维护,VS Code 中启用后常出现崩溃、跳转失败、高 CPU 占用等问题,而 clangd 是 LLVM 官方维护、LSP 实现最成熟的 C/C++ 语言服务器。
为什么 clangd 是唯一推荐选项
clangd 不仅是 VS Code 官方文档明确推荐的 C/C++ 语言服务器,也是 CLion、Neovim(通过 nvim-lspconfig)、Zed 等主流工具默认集成的后端。ccls 虽曾因内存占用低被部分嵌入式项目选用,但其对 C++20 模块、模板推导、宏展开等新特性的支持已严重滞后——比如 std::span 的类型推导在 clangd 中能正确补全,在 ccls 中大概率返回 unknown type。
- clangd 自带
--background-index,可异步索引整个项目,不阻塞编辑 - ccls 的
index命令需手动触发,且索引过程常卡死在parseInclude阶段 - VS Code 插件市场中
ccls扩展已下架,仅存的第三方版本无更新记录(最后提交为 2022 年)
clangd 插件安装与冲突规避
VS Code 中不能同时启用 C/C++(ms-vscode.cpptools)和 clangd 插件,二者会争夺同一语言服务器端口并导致跳转失效或补全空白。
- 按
Ctrl + Shift + X打开扩展面板,搜索C/C++,禁用所有相关扩展(包括C/C++ Themes、C/C++ Extension Pack) - 再搜索
clangd,安装由clangd官方发布的扩展(发布者为clangd,非个人账号) - 若已安装过
cpptools且未禁用,重启 VS Code 后打开 C++ 文件时,状态栏右下角会显示cpptools is active—— 此时 clangd 不会启动
compile_commands.json 必须存在且路径正确
clangd 依赖 compile_commands.json 获取每个源文件的完整编译参数(含 -I、-D、--std= 等),缺失或路径错位会导致头文件找不到、宏未定义、标准库类型无法识别等现象,典型错误如:'vector' file not found 或 no member named 'size' in 'std::string'。
- CMake 项目:编译时加
-DCMAKE_EXPORT_COMPILE_COMMANDS=ON,例如cmake -B build -DCMAKE_EXPORT_COMPILE_COMMANDS=ON,生成的compile_commands.json默认在build/目录下 - Makefile 项目:用
bear生成,执行前先make clean,再运行bear -- make(bear 3.0+) - 配置 clangd 启动参数时,必须显式指定
--compile-commands-dir,例如:"clangd.arguments": ["--compile-commands-dir=${workspaceFolder}/build"]
交叉编译项目要重定向 clangd 和 clang 路径
直接使用系统自带的 clangd 二进制处理 ARM/STM32/RISC-V 项目,会导致目标平台头文件路径错乱、内建宏(如 __ARM_ARCH_7A__)未定义,最终表现为所有硬件寄存器访问报错、CMSIS 头文件红色波浪线。
- 不要改
PATH,而是在.vscode/settings.json中硬编码路径:"clangd.path": "/opt/gcc-arm-none-eabi/bin/clangd" - 确保该
clangd与你交叉编译链中的clang版本一致(例如都来自 LLVM 16) - 若用 NDK,路径类似:
"clangd.path": "${env:ANDROID_NDK_HOME}/toolchains/llvm/prebuilt/linux-x86_64/bin/clangd" - 验证方式:在终端中运行该路径下的
clangd --version,输出应包含目标三元组,如armv7a-linux-androideabi
最容易被忽略的是 compile_commands.json 中的命令是否真实可用——它可能记录了绝对路径的旧编译器(如 /usr/bin/arm-gcc-9),而你当前环境只有 /opt/gcc-arm/bin/arm-gcc。此时 clangd 会静默失败,不报错也不补全。务必打开该 JSON 文件,检查任意一条 command 字段能否在 shell 中直接粘贴执行成功。











