WSL Ubuntu 搭建 ESP-IDF:工具链机制与串口烧录的取舍

WSL Ubuntu 搭建 ESP-IDF:工具链机制与串口烧录的取舍
乔阳ESP32 开发绕不开 ESP-IDF。在 Windows 上原生机装一套也能跑,但 CMake、Python、make 这些工具在 Windows 下总有些水土不服,碰到组件脚本里写死 Linux 路径就更头疼。这篇文章记录我在 WSL2 Ubuntu 下搭 ESP-IDF 的过程,顺便讲清楚工具链机制和串口烧录这块的取舍。
为什么选 WSL 而不是原生 Windows 或虚拟机
先说结论:ESP-IDF 官方提供 Windows 安装器,能用,但开发体验不如 Linux。原因有几方面。
第一,ESP-IDF 的构建系统基于 CMake 加 Ninja,大量组件脚本(Python、shell)按 POSIX 假设编写。Windows 下偶尔会遇到路径分隔符、符号链接、shell 调用之类的问题,排查起来打断节奏。
第二,ESP-IDF 的文档和社区示例默认 Linux/macOS,复制粘贴一条命令就能跑的概率更高。
虚拟机方案能解决工具链问题,但开销大:要分配独立内存和磁盘,文件在宿主机和虚拟机之间来回拷,启动慢。WSL2 给的是真正的 Linux 内核,启动几乎瞬时,和 Windows 共享剪贴板、文件系统(通过 \\wsl$ 访问),用 VS Code Remote-WSL 直接接进 WSL 里的项目,体验接近原生 Linux 开发。
不过 WSL2 不是没代价。最大的坑是 USB 和串口访问,这块后面单独说。
ESP-IDF 工具链是怎么组织的
动手装之前,先搞清楚 ESP-IDF 到底装了什么,避免后面遇到环境变量问题一头雾水。
ESP-IDF 分三部分:
- 框架源码(
esp-idf仓库):包含组件库(WiFi、蓝牙、外设驱动等)、构建系统脚本、idf.py命令行工具的 Python 实现。通过git clone --recursive拉下来。 - 交叉编译工具链:ESP32 是 Xtensa 架构(S2/S3 也是),C3/C6 是 RISC-V。这些交叉编译器(
xtensa-esp32-elf-gcc、riscv32-esp-elf-gcc)不在 esp-idf 仓库里,install.sh会单独下载到~/.espressif/下。 - Python 虚拟环境:
idf.py及大量构建脚本用 Python 写,依赖一堆包。install.sh会在~/.espressif/python_env/建一个独立 venv,避免污染系统 Python。
install.sh 干的事就是下载工具链、建 venv、装 Python 依赖。装完之后,工具链和 venv 都在 ~/.espressif/,和 esp-idf 源码目录分离。这意味着同一台机器可以装多个 IDF 版本,每个版本跑一次 install.sh 就行,切换时 source 对应的 export.sh。
export.sh 在做什么
每次开新终端,idf.py 都找不到,原因是没有环境变量。export.sh 做三件事:
- 设置
IDF_PATH指向 esp-idf 源码目录 - 把交叉编译器、CMake、Ninja 等工具路径加进
PATH - 激活
~/.espressif/python_env/里那个 Python venv
所以 export.sh 不是”配置一次永久生效”的脚本,它是每个终端会话都要 source 一次的激活脚本。理解了这点,后面的别名方案就好懂了。
步骤一:准备 Ubuntu 环境
先更新系统并装依赖。这些包是 ESP-IDF 官方文档列出的,缺一个可能影响构建:
1 | sudo apt update && sudo apt upgrade -y |
前提是已经装好 WSL2 和 Ubuntu 发行版。如果访问 GitHub 慢,提前配好代理。
步骤二:拉 ESP-IDF 源码
1 | mkdir -p ~/development/esp |
--recursive 必须加。ESP-IDF 的子模块(components 里的第三方库)很多,不带 recursive 会缺东西,构建时再报错更难定位。
克隆慢的话用 Gitee 镜像:
1 | git clone -b v5.5.1 --recursive https://gitee.com/EspressifSystems/esp-idf.git |
注意 Gitee 镜像不一定同步所有子模块,偶尔会碰到某个子模块拉不下来。遇到这种情况,可以进入对应子模块目录手动切换 remote,或者配代理直连 GitHub。
步骤三:装工具链
1 | cd ~/development/esp/esp-idf |
install.sh 后面的参数指定要装哪些芯片的工具链。不传的话默认装所有支持的目标,体积会比较大。我常用 S3,加上 32 和 S2 备用,按需选就行。
脚本会下载交叉编译器、建 Python venv、装依赖。按网络情况,10 到 30 分钟正常。装完工具链在 ~/.espressif/,不污染 esp-idf 源码目录。
如果中途失败(常见原因是网络中断或磁盘满),清掉重来:
1 | rm -rf ~/.espressif |
步骤四:激活环境
1 | . ./export.sh |
能打印版本号就说明 PATH 和 venv 都对了。
每个终端都要 source 一次 export.sh 很烦。官方推荐的做法是加个别名,需要时再激活:
1 | # 加到 ~/.zshrc 或 ~/.bashrc |
然后 source ~/.zshrc,之后每个终端里敲 get_idf 就激活环境。
不要图省事把 . export.sh 直接写进 .zshrc。这样每个终端都会激活 IDF 的 Python venv,包括你写别的 Python 项目、跑别的工具的终端,会污染全局 Python 环境。用别名按需激活才符合 venv 的设计意图。
步骤五:建项目并构建
1 | mkdir -p ~/projects/esp32 |
set-target 会根据芯片配置项目(选择对应的工具链、sdkconfig 默认值)。常见目标:esp32、esp32s2、esp32s3、esp32c3。
构建成功会打印固件大小和内存占用,build/ 目录下生成 .bin 文件。
验证编译器:
1 | xtensa-esp32s3-elf-gcc --version |
注意编译器名字带芯片型号,换目标后名字也变(比如 C3 是 riscv32-esp-elf-gcc)。
文件系统位置影响构建速度
这是个容易被忽略的坑。WSL2 里访问 Windows 文件系统(/mnt/c/...)要走 9P 协议,IO 性能比 WSL 原生文件系统(~/,即 ext4)差很多。把项目放在 /mnt/c/ 下构建,时间可能是放在 ~/ 下的好几倍。
所以项目目录一定放在 WSL 原生文件系统里,比如 ~/projects/。需要用 Windows 工具看文件时,通过 \\wsl$\Ubuntu\home\... 访问。
串口烧录:WSL2 最大的痛点
到这一步,构建没问题,但烧录会卡住。WSL2 默认看不到 USB 设备,自然也看不到 USB 转串口芯片(CP2102、CH340 之类),/dev/ttyUSB0 不会出现。
有两条路。
方案一:从 Windows 侧烧录。 在 Windows 上单独装一套 ESP-IDF(用官方 installer),或者只装 esptool。构建在 WSL 里完成,把 build/*.bin 拷到 Windows 下用 Windows 的 esptool 烧。好处是稳定,坏处是要维护两套环境,或者手动拷文件。
方案二:用 usbipd-win 把 USB 设备桥接进 WSL。 usbipd-win 是微软官方的工具,能把 Windows 上的 USB 设备 attach 到 WSL2 里。装好后在 Windows PowerShell 里执行:
1 | usbipd list # 列出 USB 设备,找到 ESP32 开发板的 BUSID |
attach 之后 WSL 里就能看到 /dev/ttyUSB0,然后正常 idf.py -p /dev/ttyUSB0 flash。
这条路能跑通,但每次插拔都要重新 attach,而且需要内核支持 usbipd(较新的 WSL2 内核自带)。调试时频繁烧录的话体验不如原生 Windows 或直接用 Linux 机器。
我的实际做法是:日常开发在 WSL(编辑、构建、菜单配置都在 WSL),烧录时如果频繁就切到 Windows 侧的 esptool,偶尔烧一次就用 usbipd。
关于版本和更新
ESP-IDF 版本迭代比较快,v5.x 是当前的稳定主线。固定一个版本(比如这里的 v5.5.1)开发是有意义的,避免中途升级引入兼容问题。需要升级时,重新 git checkout 新版本,git submodule update --init --recursive,再跑一次 install.sh(会装新版本对应的工具链),不影响旧版本。
不同项目用不同 IDF 版本时,每个版本 clone 到不同目录(比如 ~/development/esp/esp-idf-v5.5.1、~/development/esp/esp-idf-v5.4.1),每个跑一次 install.sh,然后 get_idf 别名做成多版本切换:
1 | alias get_idf_v551=". $HOME/development/esp/esp-idf-v5.5.1/export.sh" |
小结
WSL2 搭 ESP-IDF 在构建和编辑体验上接近原生 Linux,比原生 Windows 顺手,比虚拟机轻量。主要代价是 USB 串口烧录要绕一层(usbipd-win 或 Windows 侧 esptool)。如果你的工作流是”WSL 构建 加 偶尔烧录”,这个组合值得用;如果每分钟都要烧一次做调试,单独弄台 Linux 机器或直接用 Windows installer 可能更省心。







