ESP-IDF 在 Windows + Git Bash 下编译:三个必踩的坑

MSYSTEM 环境变量导致 idf.py 静默跳过 main()、工具链 PATH、以及沙箱 TEMP 目录——三个坑都实测过,直接给解法。

在 Windows 上用 Git Bash 驱动 ESP-IDF 编译,官方文档基本没覆盖,网上资料也是零散的。这篇是实测结论,三个坑缺一不可。

坑一:MSYSTEM 让 idf.py 静默跳过 main()

症状最迷惑:编译成功、烧录成功,但固件里 app_main 根本没执行——因为 idf.py 检测到 MSYSTEM 环境变量(Git Bash 必设)后,某些代码路径直接把构建目标当成了别的东西,main 组件被静默跳过。

关键在于:在 bash 里 unset MSYSTEM 没用。试过 env -u MSYSTEM、cmd /c set MSYSTEM= 再调用,统统无效——因为这个变量必须在启动 Python 进程之前的 OS 层面就被拿掉,而 Python 启动后再看 os.environ 已经来不及?不,恰恰相反:必须在 Python 内部 os.environ.pop("MSYSTEM") 才有效。

所以正确做法是写一个 Python 启动器:

import os
os.environ.pop("MSYSTEM", None)   # 必须 Python 内部移除,bash 层 unset 无效
# 然后再调 idf.py 的 main

坑二:工具链 PATH 要显式 prepend

ESP-IDF 的 export 脚本在 Git Bash 下不可靠,cmake / ninja / ccache / xtensa-gcc 需要手动加进 PATH:

tools = r"D:\Espressif\tools"
for p in ["cmake\\3.x.x\\bin", "ninja", "ccache", "xtensa-esp-elf\\esp-13.x\\xtensa-esp-elf\\bin"]:
    os.environ["PATH"] = os.path.join(tools, p) + os.pathsep + os.environ["PATH"]

另外 ESP_ROM_ELF_DIR 也要设,否则 openocd/rom 相关步骤报错。venv 在 D:\Espressif\python_env\ 下找。

坑三:TEMP 指向不可写目录

某些受控环境(沙箱、受限账号)里 %TEMP% 不可写,构建中途炸出莫名其妙的权限错误。解法:

for var in ("TMP", "TEMP", "TMPDIR"):
    os.environ[var] = os.path.join(project_dir, ".workbuddy", "tmp")
os.makedirs(os.environ["TMP"], exist_ok=True)

结论

把上面三件事 + ESP_ROM_ELF_DIR 打包成一个 Python 启动器脚本,之后一条命令编译,不再碰 .bat / export.bat。踩一次坑就够,别踩第二次。