#!/usr/bin/env bash # One-time (idempotent) environment bootstrap for compiling the # espresso_frame firmware (firmware/) without Docker -- see this # skill's SKILL.md for why not Docker, even though that's what CI uses. # Re-run any time; every step is safe/fast to repeat once already done. set -euo pipefail IDF_ROOT="$HOME/.espressif-idf" IDF_DIR="$IDF_ROOT/esp-idf" # Matches the espressif/idf:release-v6.0 image CI's # firmware-build-check.yml/firmware-release-build.yml use -- keep this # in sync with those workflow files if the project's pinned IDF version # ever changes. IDF_BRANCH="release/v6.0" # 1. OS packages ESP-IDF's own install.sh needs (python3 + venv/pip, # cmake, ninja, a C toolchain for the odd host-side code generator, git # for the clone below, flex/bison/gperf for mbedtls/etc.'s generated # parsers, libusb for esptool's USB/JTAG bits even though this skill # doesn't flash real hardware). Installed via apt with real root -- # unlike run-server's Chromium bootstrap, this container actually has # root and a working apt, so no non-root extraction dance is needed # here. PKGS="git python3 python3-venv python3-pip cmake ninja-build ccache libusb-1.0-0 wget flex bison gperf build-essential" missing=() for pkg in $PKGS; do dpkg -s "$pkg" >/dev/null 2>&1 || missing+=("$pkg") done if [ ${#missing[@]} -gt 0 ]; then echo "installing OS packages: ${missing[*]}" apt-get update DEBIAN_FRONTEND=noninteractive apt-get install -y "${missing[@]}" fi # 2. ESP-IDF checkout -- shallow, single branch, recursive submodules # also shallow (~700MB total, vs. several GB for a full clone). Only # clones once; re-running this script never re-clones or resets it, so # any local changes you made for debugging survive a re-run. if [ ! -d "$IDF_DIR/.git" ]; then echo "cloning esp-idf $IDF_BRANCH into $IDF_DIR ..." mkdir -p "$IDF_ROOT" git clone --branch "$IDF_BRANCH" --depth 1 --shallow-submodules --recursive \ https://github.com/espressif/esp-idf.git "$IDF_DIR" else echo "esp-idf already cloned at $IDF_DIR" fi # 3. Toolchain + Python virtualenv, scoped to esp32c6+esp32s3 only -- # this project's two chip targets (see firmware/README.md's board # table: devkit/xiao are esp32c6, ee02 is esp32s3). Scoping avoids # downloading toolchains for every chip ESP-IDF supports, which matters # given this container's disk headroom. install.sh is already # idempotent on its own (checks what's present and skips it), so this # always calls it rather than trying to duplicate that check here -- # a re-run only costs a few seconds once everything's cached. echo "running esp-idf install.sh esp32c6,esp32s3 (fast if already installed) ..." (cd "$IDF_DIR" && ./install.sh esp32c6,esp32s3) echo "setup complete -> $IDF_DIR/export.sh (build.sh sources this for you)"