The place where random ideas get written down and lost in time.
2025-10-01 - ESP-RS: Setup with MSYS2
Category Esp32
Since I’ve installed Rust for my exploratory ESP32 project twice already on different machines, I decided to actually write down my install instructions. There are a couple tricks I need to remember.
These steps are for MSYS2 on Windows. I used similar steps on my other box where I use my old fashioned Cygwin. Part of these instructions also work with PowerShell if you hate yourself that much.
My default shell is the “purple” MSYS2 MSYS one (the other shells are MinGW UCRT/Clang x86/x64; I can never remember why I would care about the difference so don’t ask me).
I already have Rust installed on this machine. I likely used “Rustup” following the default Rust install instructions.
I always customize ~/.bash_aliases, where I already added a line that sets up Rust and reminds me it’s available:
if [[ -d "$USERPROFILE/.cargo/bin" ]]; then
RUST_PATH=$(cygpath "$USERPROFILE/.cargo/bin")
export PATH="$PATH:$RUST_PATH"
echo "Rust Cargo: installed."
fi
So first let’s check we have Rust and which version:
$ rustup -V
rustup 1.28.2 (e4f3ad6f8 2025-04-28)
info: The currently active `rustc` version is `rustc 1.86.0 (05f9846f8 2025-03-31)`
$ rustup show
Default host: x86_64-pc-windows-msvc
rustup home: C:\Users\$USER\.rustup
Of note: there is no “esp” toolchain installed (yet).
OK now we need to install a bunch of stuff:
$ cargo install ldproxy # time: < 5 minutes
$ cargo install espup --locked # time: < 5 minutes
$ espup install --default-host x86_64-pc-windows-msvc --targets esp32,esp32s2
# time: < 1 minutes
# “espup” generates the “export-esp.ps1” that we’ll need later
$ ls -la "C:\Users\$USER\export-esp.ps1"
# At that point we have a usable “esp” toolchain. We used ~3 GB of disk space.
# We just need the “espflash” tool.
$ cargo install espflash --locked # time ~3 minutes
Optionals tools we can install and build:
$ cargo install esp-generate --locked
$ cargo install esp-config --features=tui --locked
I don’t use esp-generate nor esp-config so I just skip them. “esp-generate” is useful to create a barebone no_std project or clone a canonical esp-rs/std one, but I basically do that by cloning my own canonical git sample:
$ git clone git@github.com:ralfoide/arduino.git
$ cd ESP32-CAM/Rust/esp-rs-std-blinky
$ echo “don’t run cargo build yet”
At that point, we could build a project, except that it will fail.
The first “cargo build” or “cargo run” we’ll do with an “esp-idf-sys” crate is going to perform an entire checkout of the ESP-IDF toolchain (complete with its own Python env, etc) and build it locally. That will take an extra 3.8 GB once it succeeds, except it will never succeed at first. The main issue is that the ESP-IDF build generates paths which are much longer than what the Windows shell can support. So read below before trying to build.
Customize the ESP-IDF Toolchain Location
By default, “cargo build” will generate a “.embuild” folder in the current project directory, and proceed to perform an entire git checkout of the ESP-IDF toolchain in there and build it. This build has very long paths, and it happens in your own development folder that itself can have fairly long paths. The result is a failure due to the path being longer than Windows can deal with.
You’ll get errors like this:
$ cargo build
D:/github/ralfoide/arduino/ESP32-CAM/RustExperiment/esp-rs-exp/.embuild/espressif/esp-idf/v5.2.3/components/mbedtls/port/esp_hardware.c:25:1: fatal error: opening dependency file esp-idf\mbedtls\mbedtls\library\CMakeFiles\mbedcrypto.dir\d6d36c90cb3cc8680c2d3a46d0c7f9c4\esp_hardware.c.obj.d: No such file or directory
error: failed to run custom build command for `esp-idf-sys v0.36.1`
Caused by:
process didn't exit successfully: `D:\github\ralfoide\arduino\ESP32-CAM\RustExperiment\esp-rs-exp\target\release\build\esp-idf-sys-e4b83c89877131ec\build-script-build` (exit code: 1)
--- stderr
Error: Too long output directory: `\\?\D:\github\ralfoide\arduino\ESP32-CAM\RustExperiment\esp-rs-exp\target\xtensa-esp32-none-elf\release\build\esp-idf-sys-405b878788241d10\out`. Shorten your project path down to no more than 10 characters (or use WSL2 and its native Linux filesystem). Note that tricks like Windows `subst` do NOT work!
I’m not interested in moving my development folder, and I definitely do not want to deal ever again with WSL2. Luckily, there’s a much easier solution to this problem: the ESP-IDF location does not have to be located in the project’s folder at all.
Simply edit .cargo/config.toml in your project and customize the ESP-IDF location:
$ vim .cargo/config.toml
[env]
ESP_IDF_PATH_ISSUES = "warn"
ESP_IDF_TOOLS_INSTALL_DIR = { value = "global" }
There are 2 variables to add:
- “ESP_IDF_PATH_ISSUES” tells the build system to print suspiciously long path but do not abort the build.
- “ESP_IDF_TOOLS_INSTALL_DIR” indicates where to install the ESP-IDF folder as described in the esp-idf-sys documentation. The default is “workspace”. A custom directory could be specified. However in my case, “global” works very nicely and it defaults to $USERPROFILE/.espressif (a.k.a. C:\Users\$USER\.espressif).
For my use case, one advantage of “global” is that if you have multiple projects, they will share the same ESP-IDF install. That directly has one sub-dir per ESP-IDF version. Thus I allocate only 3.8 GB for that ESP-IDF install globally instead of per-project.
Enable Win32 Long Path Supports
This MUST be enabled or the ESP-IDF install will fail:
- gpedit.msc > run as admin
- Local computer > Computer config > Admin Templates > System > Filesystem
- “Enable Win32 long path” → enable
- Reboot
I don’t know why modern Windows installs don’t just enable this by default. There’s no downside to having the long path support AFAIK.
PowerShell: Check Python with PowerShell
The PowerShell build first failed because “Python.exe” could not be found.
On the Cygwin box, that wasn’t a problem, and this machine does have the Windows Python 3.11 installed but it’s apparently not in the main $Env:PATH used by PowerShell.
I guess I could reinstall Python and not forget the “add to PATH” checkbox in the installer, but that’s boring when I can simply alter the “export-esp.ps1” script to add Python to the PATH:
> vim C:\Users\$Env:USERNAME\export-esp.ps1
> $Env:PATH="C:\Users\$Env:USERNAME\AppData\Local\Programs\Python\Python311;"+$Env:PATH
Check it’s available in PowerShell:
> python --version
Python 3.11.2
PowerShell: Allow to Execute Scripts
Open PowerShell and run this command once to allow execution of the ps1 script:
> Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy Unrestricted
Now we can run the script to change the PATH:
> C:\Users\$Env:USERNAME\export-esp.ps1
Build esp-idf-sys Once with PowerShell
Although I want to use MSYS2 later, the first build of the “esp-idf-sys” crate is special. It performs an entire git checkout of the ESP-IDF toolchain and builds many of the tools once. I found that this step worked with Cygwin yet it always failed with MSYS2 due to a path style mismatch. The solution is to build the project once with PowerShell, then we can use the regular MSYS2 for followup builds.
> cd C:\github\ralfoide\arduino\ESP32-CAM\Rust\esp-rs-std-webcam\
> C:\Users\$Env:USER\export-esp.ps1
> date ; cargo build -vv ; date
That took about 7 minutes for esp-idf-sys and ~7 minutes for the other crates.
Once this is built once, I’ve noticed it’s then possible to build from MSYS2 as expected:
<MSYS2>
$ carbo build -vv --release
⇒ that works now.