From eb8202058fccc928cc27da04a676efa3bc1df1df Mon Sep 17 00:00:00 2001 From: Stephen Waits Date: Tue, 28 Apr 2026 11:15:36 -0600 Subject: [PATCH] build: declare ESP toolchain in mise.toml; drop ~/export-esp.sh dependence mise.toml now owns the ESP cross-toolchain end to end: - [env] pins PATH (xtensa-esp-elf-gcc bin) and LIBCLANG_PATH so any `mise exec` (which the justfile already uses for `set shell`) resolves the linker without sourcing espup's stray ~/export-esp.sh. - [tasks.esp-install] installs the matching crosstool version via espup (espup hardcodes ~/.rustup/toolchains/esp/ -- there is no --prefix flag -- so the binaries necessarily live there, but the project now declaratively owns the version + path knowledge). - cargo:espup pinned to 0.17.1 to match the [env] paths. Triggered by a real failure: ~/export-esp.sh was moved to Trash and the ESP build broke with `linker xtensa-esp32s3-elf-gcc not found`. The previous setup silently no-op'd `[ -f $HOME/export-esp.sh ] && . $HOME/export-esp.sh` in justfile, leaving the build with no PATH for the cross-toolchain. Encoding the paths in mise.toml removes the stray-file dependency. justfile changes: - _cargo: drop the `[ -f $HOME/export-esp.sh ] && . ...` source. - setup / _require_esp_toolchain: install via `mise run esp-install` instead of bare `espup install`, so the version pin and the [env] paths stay in sync from a single source. Bumping ESP versions remains a two-touch change: edit the version dirs in BOTH [tasks.esp-install] and [env], then re-run the task. --- justfile | 18 ++++++++++-------- mise.toml | 26 ++++++++++++++++++++++++-- 2 files changed, 34 insertions(+), 10 deletions(-) diff --git a/justfile b/justfile index 74cb0ea..c40e935 100644 --- a/justfile +++ b/justfile @@ -19,10 +19,11 @@ boards := "heltec_v3 heltec_v3_uart heltec_v4 elecrow_thinknode_m2 lilygo_tbeam setup: mise trust --yes mise install - @# ESP Xtensa toolchain (not a rustup component — installed out-of-band by espup) + @# ESP Xtensa toolchain — installed via the `esp-install` mise task + @# (which pins versions to match mise.toml's [env] paths). @if ! rustup toolchain list | grep -q "^esp"; then \ - echo "ESP toolchain not found, installing via espup (this may take a while)..."; \ - espup install || { echo "error: espup install failed" >&2; exit 1; }; \ + echo "ESP toolchain not found, installing via mise task (this may take a while)..."; \ + mise run esp-install || { echo "error: esp-install task failed" >&2; exit 1; }; \ fi # Build release firmware for all boards, installing toolchains as needed @@ -154,7 +155,6 @@ _cargo board cmd extra_args="" extra_features="": extra=""; buildstd=""; \ case "$target" in xtensa-*) \ just _require_esp_toolchain; \ - [ -f "$HOME/export-esp.sh" ] && . "$HOME/export-esp.sh"; \ extra="+esp"; buildstd="-Zbuild-std=core,alloc";; \ esac; \ cargo $extra {{cmd}} --target "$target" --features "$feat" $buildstd {{extra_args}} @@ -168,15 +168,17 @@ _can_build board: *) rustup target list --installed | grep -q "^$target$" || rustup target add "$target" ;; \ esac -# Ensure the ESP Xtensa toolchain is installed (espup installed via mise). -# The esp toolchain ships with its own cargo, rustc, and rust-src — no extra +# Ensure the ESP Xtensa toolchain is installed. The actual install is +# delegated to the `esp-install` mise task so the version pin lives in +# mise.toml alongside the matching [env] PATH/LIBCLANG_PATH entries. +# The esp toolchain ships its own cargo, rustc, and rust-src — no extra # components are needed on top. [private] _require_esp_toolchain: @just _ensure_tools @if ! rustup toolchain list | grep -q "^esp"; then \ - echo "ESP toolchain not found, installing via espup (this may take a while)..." >&2; \ - espup install || { echo "error: espup install failed" >&2; exit 1; }; \ + echo "ESP toolchain not found, installing via mise task (this may take a while)..." >&2; \ + mise run esp-install || { echo "error: esp-install task failed" >&2; exit 1; }; \ fi # Find a serial port matching any of the given VID:PID pairs (checked in order) diff --git a/mise.toml b/mise.toml index 0caae60..cfc1860 100644 --- a/mise.toml +++ b/mise.toml @@ -4,7 +4,7 @@ just = "latest" # Cargo-installed tooling via mise's `cargo:` backend. "cargo:cargo-binutils" = "latest" # rust-objcopy, rust-size "cargo:cargo-hex-to-uf2" = "latest" # ELF → UF2 for nRF52 / RP2040 DFU drives -"cargo:espup" = "latest" # bootstraps the ESP Xtensa toolchain +"cargo:espup" = "0.17.1" # ESP Xtensa toolchain installer (pinned: [env] paths below match this version's defaults) "cargo:espflash" = "3" # flash + save-image for ESP targets (4.x requires esp_app_desc!() in app — revisit alongside esp-hal 1.1+ / drop-the-patches cleanup) "cargo:probe-rs-tools" = "latest" # debug-probe flash/run for ARM targets @@ -13,7 +13,7 @@ just = "latest" # extra `rustup target add` step at setup time. # # Xtensa ESP targets are NOT listed here — they use the self-contained `esp` -# toolchain installed out-of-band by `espup` (see `just setup`). That +# toolchain populated by `mise run esp-install` (see [tasks] below). That # toolchain ships its own rust-src for `-Zbuild-std`. # # profile = "minimal" (just rustc, rust-std, cargo), "default" (adds rust-docs, rustfmt, clippy) @@ -22,3 +22,25 @@ just = "latest" version = "1.94" profile = "default" targets = "thumbv6m-none-eabi,thumbv7em-none-eabihf" + +# ESP Xtensa toolchain. `cargo:espup` above only installs the *installer*; +# the actual rustc-esp + xtensa-esp-elf-gcc + esp-clang toolchains are +# populated by `mise run esp-install` (or `just setup`). +# +# espup hardcodes its install root to ~/.rustup/toolchains/esp/ — there's +# no --prefix or --install-dir flag — so the binaries necessarily live +# there. The [env] block below pins the exact PATH and LIBCLANG_PATH so +# every `mise exec` (which the justfile uses for `set shell`) resolves +# the cross-toolchain without depending on espup's stray ~/export-esp.sh. +# +# Bumping versions: edit the version dirs in BOTH [tasks.esp-install] (so +# espup installs the matching crosstool) AND [env] (so the path resolves). +[env] +_.path = [ + "{{env.HOME}}/.rustup/toolchains/esp/xtensa-esp-elf/esp-15.2.0_20250920/xtensa-esp-elf/bin", +] +LIBCLANG_PATH = "{{env.HOME}}/.rustup/toolchains/esp/xtensa-esp32-elf-clang/esp-20.1.1_20250829/esp-clang/lib" + +[tasks.esp-install] +description = "Install the ESP Xtensa toolchain (rustc-esp + GCC + clang) at versions matching [env]" +run = "espup install --crosstool-toolchain-version esp-15.2.0_20250920"