为 ESP-IDF 配置 Clangd

ESP-IDF 是一个好用的开发框架,但它的构建目标通常是 Xtensa 架构的芯片,工具链也与桌面开发环境不同。这导致了在使用 Clangd 作为 LSP 服务器时,可能会遇到一些配置上的挑战。下面是一个经过验证的配置方法,可以正确地为 ESP-IDF 项目设置 Clangd。

构建 LLVM

一般的 LLVM 构建并不能识别 xtensa-esp32-elf 这样的工具链,因此我们需要使用 ESP-IDF 官方提供的 LLVM 构建版本。

# clone the llvm-project repository
cd ~/.espressif/
git clone https://github.com/espressif/llvm-project.git

# build the llvm-project
cd llvm-project
cmake -S llvm -B build -G Ninja -DLLVM_ENABLE_PROJECTS="clang;clang-tools-extra" -DCMAKE_BUILD_TYPE=Release
cmake --build build

构建过程可能需要将近一个小时。

配置 Clangd

以 VSCode 为例,我们安装 Clangd 扩展后,在 settings.json 中添加以下配置:

{
    "clangd.path": "/home/your-user-name/.espressif/llvm-project/build/bin/clangd",
    "clangd.arguments": [
    "--background-index",
    "--query-driver=**",
    "--compile-commands-dir=${workspaceFolder}/build"
    ],
}

如此即可使用刚才构建的 Clangd,同时找到 ESP-IDF 项目的 compile_commands.json 文件,提供正确的代码分析和智能提示。该文件在至少经过一次正确构建后会生成在 build 目录下。

经过上面的配置后,编辑器里可能仍然会提示一些关于未知 flag 的警告:

Unknown argument: '-mdisable-hardware-atomics'
Unknown argument: '-fno-shrink-wrap'
Unknown argument: '-fstrict-volatile-bitfields'
Unknown argument: '-fno-tree-switch-conversion'

这是因为 ESP-IDF 的构建系统会添加一些特定于 Xtensa 架构的编译选项,这些选项在 Clangd 中可能不被识别。虽然这些警告不会影响代码分析的功能,但如果想要消除这些警告,可以在项目根目录 (或者某个父目录)下创建一个 .clangd 文件,内容如下:

CompileFlags:
  Remove: [-f*, -m*]

或者只移除报错的 flag:

CompileFlags:
  Remove:
    - -mdisable-hardware-atomics
    - -fno-tree-switch-conversion
    - -fstrict-volatile-bitfields
    - -fno-shrink-wrap

版本信息

  • ESP-IDF v5.5.2
  • llvm-project commit
  • Clangd extension 0.4.0