在 code-server 中开发 ESP-IDF 项目并启用 clangd 的环境配置
在服务器上部署 code-server,然后安装 ESP-IDF 开发环境并配置 clangd 以实现代码补全和语法检查。
这篇文章就是三合一:code-server 的安装、ESP-IDF 的安装、ESP-IDF 在 code-server 中的配置。当然第三部分也可以理解为在 VSCode 里面配好 ESP-IDF 的开发环境,并启用 clangd。前面两步非常简单,第三步稍微复杂一点,但是也不难。
安装 code-server#
这里用最简单的方式之一安装 code-server,使用 linuxserver.io ↗ 的 docker 镜像 ↗。
照着他们给出的说明,直接使用 docker 命令行或者 docker compose 都可以,有几点要注意的地方。
- 环境变量
PASSWORD
或HASHED_PASSWORD
建议设置,否则所有知道 coder-server 地址的人都可以访问。 - 环境变量
SUDO_PASSWORD
或SUDO_PASSWORD_HASH
一定要设置,因为安装 ESP-IDF 需要用到 sudo。 - 密码和密码的哈希值任选其一设置即可,如果两者都设置,我不知道会发生什么。
- 密码哈希值的创建方法在 code-server 文档的高频问答 ↗中有说明,但是给出的方法已过期,可以使用其它方法代替,如果你找到并愿意分享给我,请与我联系。
这里贴出在写这篇文章时,他们给出的 dockercompose.yml
文件内容:
---
services:
code-server:
image: lscr.io/linuxserver/code-server:latest
container_name: code-server
environment:
- PUID=1000
- PGID=1000
- TZ=Etc/UTC
- PASSWORD=password #optional
- HASHED_PASSWORD= #optional
- SUDO_PASSWORD=password #可选,但在安装 ESP-IDF 时需要
- SUDO_PASSWORD_HASH= #可选,但在安装 ESP-IDF 时需要
- PROXY_DOMAIN=code-server.my.domain #optional
- DEFAULT_WORKSPACE=/config/workspace #optional
volumes:
- /path/to/code-server/config:/config
ports:
- 8443:8443
restart: unless-stopped
yaml直接 docker compose up -d
即可,然后访问端口 8443 就可以看到 code-server 的页面了。
安装 ESP-IDF#
进入 code-server 容器内部,或者网页上的终端,按照官方的说明 ↗,直接安装就可以了。
如果只是安装的话,只需要根据说明,走完第一到第三步(安装准备、获取 ESP-IDF、设置工具)就可以了,如果你还想验证安装是否成功,可以继续按照说明走下去。
这里贴上一些 Ubuntu 安装的命令,供大家参考(注意仍要以官方说明为准,因为软件会更新但文章并不会及时跟进)。
-
安装软件包:
bashsudo apt-get install git wget flex bison gperf python3 python3-pip python3-venv cmake ninja-build ccache libffi-dev libssl-dev dfu-util libusb-1.0-0
接下来的 ESP-IDF 安装可以跳过,到时候直接在 ESP-IDF 插件中安装也可以。
-
获取 ESP-IDF(下载到
~/esp/esp-idf
):
bashmkdir -p ~/esp cd ~/esp git clone --recursive https://github.com/espressif/esp-idf.git
-
设置工具:
bashcd ~/esp/esp-idf ./install.sh all
这样就安装好了 ESP-IDF,安装目录是 ~/esp/esp-idf,下一步就是开始配置 code-server 了。
配置 ESP-IDF#
安装插件#
打开 code-server,安装以下插件,插件都是可选的,不安装插件并不会影响开发 ESP-IDF 项目,但是会极其影响开发体验。
- clangd ↗(强烈建议安装,此文章的核心内容就是配置好这个)
- CMake Tools ↗ 和 CMake ↗(不用打命令,在界面点一下就生成
compile_commands.json
文件) - ESP-IDF 1.8.1 ↗(同样不用打命令就可以在界面上配置或执行 ESP-IDF 的很多东西)
以上插件都可以在 Open VSX Registry ↗ 上找到,另外无需特别去安装微软的 C/C++ 插件,因为 clangd 的使用体验比它好太多了。
上面有提到 compile_commands.json
文件,这个文件编译命令文件,clangd 会根据这个文件来进行代码补全和语法检查,所以它是不能缺少的,通过 CMake 可以生成这个文件。
特别注意: 在后续的步骤中需要调用 ESP IDF 插件的 Configure ESP-IDF Extension
指令,而目前 (2025年3月11日) 插件的最新版本是 1.9.1,
这个指令在目前的 1.9 版本都不能通过 Web 调用,所以目前的解决方法是下载 1.8 版本的插件,手动安装插件并且禁用掉插件的自动更新。
以下操作都假设已经安装好了插件。
配置 ESP-IDF 插件#
一般来说安装好 ESP-IDF 插件之后,就是插件的 Setup 页面,如果未安装 ESP-IDF,点击 EXPRESS 快速配置即可,注意版本需要选择 v5.4 及以上,如果已安装 ESP-IDF,点击 USE EXISTING SETUP 使用现有配置。
如果这个页面被关掉了,可以通过 Configure ESP-IDF Extension
命令打开。
然后选择服务器、版本、输入路径,最后点 Install 就可以了。
可以打开随便一个 ESP-IDF 项目,编译一下看看插件是不是正常安装好了。
状态栏中常用操作:
- 垃圾桶图标:清除编译缓存
- 扳手图标:编译项目
- 终端图标:打开 ESP-IDF 的终端,里面已经配置好了环境变量,不需要调用
export.sh
了
安装完毕 ESP-IDF 插件后,需要改为使用 clang 工具链,以下是几个要修改的插件设置(在 code-server 的设置页面找到这些设置):
-
clangd 需要使用 clang 工具链才能更好地工作,ESP-IDF 默认使用 GCC,为了启用 clang,要在 Custom Extra Vars 中增加一项
IDF_TOOLCHAIN
值为clang
。 -
为了能让 ESP-IDF 插件找到 esp-clang,要将 Custom Extra Paths 加上 esp-clang 二进制文件的路径, 一般是
~/.espressif/tools/esp-clang/某个版本号/esp-clang/bin
。
这是最终 ESP-IDF 的配置(注意这里只列举了上面手动设置的选项,ESP-IDF 插件在安装的时候会根据输入自动设置好很多其它的东西)
{
"idf.customExtraPaths": "/config/.espressif/tools/esp-clang/esp-18.1.2_20240912/esp-clang/bin",
"idf.customExtraVars": {
"IDF_TOOLCHAIN": "clang",
}
}
json配置好后,可以随便打开一个 ESP-IDF 项目,点击状态栏的扳手按钮开始编译,如果在输出中看到有以下字样,说明 ESP-IDF 的工具链成功切换到了 clang。
-- The C compiler identification is Clang 18.1.2
-- The CXX compiler identification is Clang 18.1.2
-- The ASM compiler identification is Clang with GNU-like command-line
bash在这里,clangd 插件的配置就完成了,接下来配置 CMake Tools 插件。
配置 CMake Tools 插件#
CMake Tools 插件的配置非常简单,仅需修改 CMake Tools 插件的环境变量 (Cmake.Enviroment),可以在设置中找到它。
-
为了能让 CMake 找到 ESP-IDF 的路径,需要添加一项
IDF-PATH
设置为 ESP-IDF 的路径,这个路径是你安装 ESP-IDF 时的路径,一般是~/esp/esp-idf
。 -
clangd 需要使用 clang 工具链才能更好地工作,ESP-IDF 默认使用 GCC,为了启用 clang,要添加一项
IDF_TOOLCHAIN
设置为clang
。 -
最后,为了能让 CMake 找到 ESP-IDF 提供的各种二进制文件,还需要将
export.sh
导出的环境变量全部追加到PATH
中,这样 CMake 才能找到 ESP-IDF 提供的工具。
如何查看到底导出了哪些环境变量呢?先在终端中执行 echo $PATH
,来记住已有的环境变量。然后再执行 export.sh
,再执行 echo $PATH
,这时候就会看到多了一些路径,这些路径就是要设置到 CMake Tools 的环境变量中的,将两个路径对比,将对于的部分追加到 CMake Tools 的 PATH
中。
最后,CMake Tools 插件的设置示例:
{
"cmake.environment": {
"IDF_PATH": "/config/esp/esp-idf",
"IDF_TOOLCHAIN": "clang",
"PATH": "/config/esp/esp-idf/components/espcoredump:/config/esp/esp-idf/components/partition_table:/config/esp/esp-idf/components/app_update:/config/.espressif/tools/xtensa-esp-elf-gdb/14.2_20240403/xtensa-esp-elf-gdb/bin:/config/.espressif/tools/riscv32-esp-elf-gdb/14.2_20240403/riscv32-esp-elf-gdb/bin:/config/.espressif/tools/xtensa-esp-elf/esp-14.2.0_20240906/xtensa-esp-elf/bin:/config/.espressif/tools/riscv32-esp-elf/esp-14.2.0_20240906/riscv32-esp-elf/bin:/config/.espressif/tools/esp32ulp-elf/2.38_20240113/esp32ulp-elf/bin:/config/.espressif/tools/openocd-esp32/v0.12.0-esp32-20240821/openocd-esp32/bin:/config/.espressif/python_env/idf5.4_py3.12_env/bin:/config/esp/esp-idf/tools:/config/.espressif/tools/esp-clang/esp-18.1.2_20240912/esp-clang/bin:${env:PATH}"
}
}
json配置好后,可以随便打开一个 ESP-IDF 项目,点击左侧 CMake 插件的 Delete Cache and Reconfigure 按钮,如果在输出中看到有以下字样,说明 ESP-IDF 的工具链成功切换到了 clang。
[cmake] -- The C compiler identification is Clang 18.1.2
[cmake] -- The CXX compiler identification is Clang 18.1.2
[cmake] -- The ASM compiler identification is Clang with GNU-like command-line
bash配置 clangd#
网上大多数 ESP-IDF 的 clangd 都要配置一大堆并且还要忽略一些编译选项,我给出来的方法并不需要这么麻烦😎。
支持最少步骤配置好 clangd 而且完美正常使用的 ESP-IDF 版本是 v5.4,这篇文章的撰写时间是 2024 年 12 月,此时正式版本号是 v5.3,必须切换至 v5.4 才能正常使用 clangd。
启动 clangd 插件后,会在右下角提示缺少 clangd,要求安装,这里不要安装,要使用 ESP-IDF 的 clangd。
ESP-IDF 的 LLVM 项目 ↗,提供一整套 clang 工具链,在这个示例中我们不用 GCC,改用 clang。
根据 IDF clang-tidy 的说明 ↗,可以不需要去 LLVM 项目下载 Release 文件直接执行以下命令,安装 clang (该工具链尚在开发中,最终版本发布后,将无需手动安装工具链)。
idf_tools.py install esp-clang
bash如果你的 ESP-IDF 版本低于 v5.4,则会安装旧的 clang 工具链,很多 C++ 的新特性都不支持,如果还是要用 v5.3 的话,尝试手动下载 LLVM 项目的最新 Release 文件并配置好,或者修改 ESP-IDF 目录里面,tools.json
文件,然后再执行上面的指令。
安装完 esp-clang 之后,找到 clangd 的位置,记住它,跟着这个文章的流程走的话,一般是 /config/.espressif/tools/esp-clang/某个版本号/esp-clang/bin/clangd
。
在 code-server 的设置中,手动指定 clangd 扩展使用的可执行文件路径 (clangd.path) 为上面找到的 clangd 路径,这样 clangd 插件就可以调用 esp-clangd 来进行代码补全和语法检查了。
还有一点要配置的是指定 compile_commands.json
所在的文件夹,不指定的话,clangd 会在项目根目录寻找它,而 ESP-IDF 项目的编译输出目录默认是 build
,所以要指定为 build
。也是在 clangd 插件的设置中,为 clangd 的参数 (clangd.arguments) 加上 --compile-commands-dir=build
即可。
这是最终 clangd 插件的配置示例:
{
"clangd.arguments": [
"--compile-commands-dir=build"
],
"clangd.path": "/config/.espressif/tools/esp-clang/esp-18.1.2_20240912/esp-clang/bin/clangd"
}
json配置好所有的东西之后,执行一遍清理,然后再重新构建项目,最后在 code-server 输入命令 clangd: Restart language server
重启一下 clangd,这时可以在状态栏里面看到 clangd 正在索引,继续观察 clangd 的输出,如果没有发现错误,并且构建索引完成后,没有在编辑器中看到任何错误(当然前提是代码确实是正确的),那么就配置成功了!
其它#
网上关于 ESP-IDF 使用 clangd 的讨论,大多数都是有关于 Neovim 的,对于 VSCode 来说,也是比较有参考价值的。
如果使用 clangd 辅助编辑,使用 GCC 编译的话,两者的行为不一样,可能会出现某个说出错了,某个又说没有错的情况发生,所以如果要用 clangd,最好是用 clang 编译。最常见的例子就是启用了 clangd 之后,会有一些 clang 不支持的编译选项报错,需要手动写文件去忽略这些选项,太不优雅了!
如果你仍有疑问,可以联系我(没开评论系统,只能邮件联系啦)。
参考#
参考文章有待完善。