neiam
/lambent-flex-c6
public · Issues · Pulls · Labels · Forks · Compare · Actions success · Badges · Packages
⭐
Log in to mark this repository.
Find the ESP-IDF build directory under either cargo layout
2131e3c · Gabriel Morell · 2026-09-16 18:56
Message
{commit_body(@commit)}
Files changed
modified
CLAUDE.md
+16
−6
@@ -268,12 +268,22 @@ pulls a new one — v5.1.1 wanted 15.0.0, v5.2.3 wants 16.0.1).
| 268 | 268 | |
| 269 | 269 | ### Other build-cache traps |
| 270 | 270 | |
| 271 | −- `cargo clean -p esp-idf-sys` does **not** clear embuild's CMake tree — it | |
| 272 | − lives at `target/<triple>/release/build/esp-idf-sys/<hash>/` (nested dir, not | |
| 273 | − cargo's `esp-idf-sys-<hash>`). A stale `CMakeCache.txt` there pinned gcc | |
| 274 | − 12.2.0 after the ESP-IDF version bump and produced | |
| 275 | − `Tool doesn't match supported version from list ['esp-13.2.0_20230928']`. | |
| 276 | − Fix: `rm -rf target/<triple>/release/build/esp-idf-sys`. | |
| 271 | +- `cargo clean -p esp-idf-sys` does **not** clear embuild's CMake tree. A stale | |
| 272 | + `CMakeCache.txt` there pinned gcc 12.2.0 after the ESP-IDF version bump and | |
| 273 | + produced `Tool doesn't match supported version from list | |
| 274 | + ['esp-13.2.0_20230928']`. | |
| 275 | +- **There are two possible paths for that tree, and this repo has both.** Older | |
| 276 | + cargo writes `build/esp-idf-sys-<hash>/out`; the cargo in | |
| 277 | + nightly-2026-04-27 writes `build/esp-idf-sys/<hash>/out`… and then writes the | |
| 278 | + flat one again. Whatever the rule is, do not assume: `tools/idf-build-dir.sh` | |
| 279 | + matches `*esp-idf-sys*/out/build` under either, and picks the one whose | |
| 280 | + `bootloader/bootloader.bin` is **newest**, because cargo leaves the old | |
| 281 | + directories in place and the stale one is indistinguishable by name. CI run | |
| 282 | + #6 failed on exactly this — a fresh tree had only the flat layout, which the | |
| 283 | + first version of that script did not match — and locally it was quietly | |
| 284 | + resolving to a month-old build directory, which is how you flash a bootloader | |
| 285 | + built from a different sdkconfig and get a boot loop instead of an error. | |
| 286 | +- To clear it: `rm -rf target/<triple>/release/build/esp-idf-sys*`. | |
| 277 | 287 | - ESP-IDF tool installation is not atomic; a mid-way failure leaves a partial |
| 278 | 288 | install that reports the same generic `Could not install all requested |
| 279 | 289 | Tools`. Re-running works, or drive it directly: |
modified
tools/idf-build-dir.sh
+30
−13
@@ -1,26 +1,43 @@
| 1 | 1 | #!/usr/bin/env bash |
| 2 | −# Print the ESP-IDF CMake build directory for the release profile. | |
| 2 | +# Print the ESP-IDF CMake build directory matching the ELF cargo just linked. | |
| 3 | 3 | # |
| 4 | −# embuild puts it under a content hash, and cargo keeps the old directory when | |
| 5 | −# the hash changes — so there can be several and only the newest is the one | |
| 6 | −# that matches the ELF cargo just linked. Picking the first alphabetically | |
| 7 | −# (which is what a glob does) is how you end up flashing a bootloader built | |
| 8 | −# from a different sdkconfig, which fails as a boot loop rather than as an | |
| 9 | −# error. Newest wins. | |
| 4 | +# Two things make this more than a glob. | |
| 10 | 5 | # |
| 11 | −# Prints nothing and exits 1 if the tree has not been built. | |
| 6 | +# **Cargo has two layouts.** Older cargo puts a build script's output at | |
| 7 | +# `build/<pkg>-<hash>/out`; newer cargo nests it as `build/<pkg>/<hash>/out`. | |
| 8 | +# A tree that has been built by both — this one has — contains both, and CI | |
| 9 | +# on a current nightly produces only the flat one. Match either. | |
| 10 | +# | |
| 11 | +# **Stale directories outlive the build that made them.** Cargo does not clean | |
| 12 | +# up when a hash changes, so there can be several and only one matches the ELF | |
| 13 | +# beside it. Taking the first alphabetically, which is what a glob does, is how | |
| 14 | +# you flash a bootloader built from a different sdkconfig — which fails as a | |
| 15 | +# boot loop rather than as an error. So: newest `bootloader/bootloader.bin` | |
| 16 | +# wins, and a directory without one is not a candidate at all, since the | |
| 17 | +# bootloader is the only reason anything asks for this path. | |
| 18 | +# | |
| 19 | +# Prints nothing and exits 1 if there is no usable directory, naming what it | |
| 20 | +# did find on stderr. | |
| 12 | 21 | set -euo pipefail |
| 13 | 22 | |
| 14 | 23 | profile=${1:-release} |
| 15 | −root="target/riscv32imac-esp-espidf/${profile}/build/esp-idf-sys" | |
| 24 | +root="target/riscv32imac-esp-espidf/${profile}/build" | |
| 16 | 25 | |
| 17 | 26 | newest="" |
| 18 | 27 | while IFS= read -r dir; do |
| 19 | − [ -d "$dir" ] || continue | |
| 20 | − if [ -z "$newest" ] || [ "$dir" -nt "$newest" ]; then | |
| 28 | + bootloader="$dir/bootloader/bootloader.bin" | |
| 29 | + [ -f "$bootloader" ] || continue | |
| 30 | + if [ -z "$newest" ] || [ "$bootloader" -nt "$newest/bootloader/bootloader.bin" ]; then | |
| 21 | 31 | newest=$dir |
| 22 | 32 | fi |
| 23 | −done < <(find "$root" -maxdepth 3 -type d -path "*/out/build" 2>/dev/null) | |
| 33 | +done < <(find "$root" -maxdepth 4 -type d -path "*esp-idf-sys*/out/build" 2>/dev/null) | |
| 34 | + | |
| 35 | +if [ -z "$newest" ]; then | |
| 36 | + echo "idf-build-dir: no ESP-IDF build directory with a bootloader under $root" >&2 | |
| 37 | + echo "idf-build-dir: candidates seen:" >&2 | |
| 38 | + find "$root" -maxdepth 4 -type d -name "out" -path "*esp-idf-sys*" 2>/dev/null >&2 || | |
| 39 | + echo " (none — has this profile been built?)" >&2 | |
| 40 | + exit 1 | |
| 41 | +fi | |
| 24 | 42 | |
| 25 | −[ -n "$newest" ] || exit 1 | |
| 26 | 43 | printf '%s\n' "$newest" |
Parents: 478e173