Files
Dan TheisenandClaude Opus 5 10aa6aa4f5 Add dev container for reproducible builds
Preconfigured VS Code dev container with the Zephyr SDK, toolchains, west
and vendor blobs matched to CI, so a build can be reproduced without
installing prerequisites on the host.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-30 15:10:33 +00:00

105 lines
4.4 KiB
Markdown

# ZephCore dev container
A ready-to-build Zephyr workspace: **Zephyr SDK 1.0.1**, **west**, and the four
toolchains ZephCore's boards need. It reproduces the environment from
[.github/workflows/build.yml](../.github/workflows/build.yml), so a local build
matches CI.
## Getting started
Open the repo in VS Code and run **Dev Containers: Reopen in Container**, or from
a terminal:
```bash
devcontainer up --workspace-folder .
```
First creation takes a while — it downloads the SDK toolchains (~1 GB), clones
Zephyr and its modules, and fetches the vendor BLE blobs. Subsequent starts are
instant.
When it finishes you can build immediately, from the workspace root:
```bash
west build -b rak4631 zephcore --pristine
west build -b xiao_esp32s3/esp32s3/procpu zephcore --pristine --sysbuild
bash build.sh nrf
```
Artifacts land in `build/zephyr/` and, for `build.sh`, `firmware/`.
## What's inside
| | |
|---|---|
| Base | `mcr.microsoft.com/devcontainers/base:ubuntu-24.04` (Python 3.12, CMake 3.28) |
| Zephyr SDK | 1.0.1 at `/opt/zephyr-sdk-1.0.1` |
| Toolchains | `arm-zephyr-eabi`, `xtensa-espressif_esp32_zephyr-elf`, `xtensa-espressif_esp32s3_zephyr-elf`, `riscv64-zephyr-elf` |
| Cross compilers | `arm-linux-gnueabihf`, `aarch64-linux-gnu` (for the `build.sh linux` native_sim presets) |
| Python | venv at `/opt/zephyr-venv`, first on `PATH` — holds `west`, `esptool`, `pyocd`, `adafruit-nrfutil`, and Zephyr's own requirements |
| Vendor blobs | `hal_espressif` and `hal_silabs` BLE controllers, fetched on create |
Only the toolchains ZephCore actually targets are installed. Adding a board on a
new architecture means adding its toolchain to `ZSDK_TOOLCHAINS` in
[devcontainer.json](devcontainer.json) (and to `toolchains` in the CI workflow)
and rebuilding the container.
## Workspace layout
The west topdir is the workspace root — the folder that *contains* `zephcore/` —
matching what `west init -l zephcore` and `build.sh` assume:
```
/workspaces/ZephCore/
├── zephcore/ the application (this git repo)
├── zephyr/ \
├── modules/ | west-managed, in named volumes
├── bootloader/ |
├── tools/ /
├── build/ on the host bind mount
└── firmware/ on the host bind mount
```
`zephyr/`, `modules/`, `bootloader/` and `tools/` live in Docker named volumes
rather than on the host bind mount. They are tens of thousands of files nobody
edits from the host, and container-native storage is several times faster for
them on Windows and macOS. `build/` and `firmware/` stay on the bind mount so you
can reach the binaries from the host to flash them.
To reclaim that space after deleting the container: `docker volume prune`, or
`docker volume ls | grep zephcore-` to remove them individually.
## Setup knobs
[post-create.sh](post-create.sh) is idempotent — re-run it any time with
`bash .devcontainer/post-create.sh`. Two environment variables change what it
does:
- `ZEPHCORE_WEST_FULL=1` — clone Zephyr and modules with full history. The
default uses `west update --narrow -o=--depth=1`, which cuts the checkout from
~5 GB to well under 1 GB. The trade-off is that `zephyr/` and the modules carry
no history and no tags, so `git log`/`git describe`/`git bisect` in them don't
work. Builds are unaffected — ZephCore's version string comes from
`ZEPHCORE_FIRMWARE_VERSION` in `zephcore/CMakeLists.txt`. Set this if you need
to dig through upstream history.
- `ZEPHCORE_SKIP_BLOBS=1` — skip the vendor BLE blobs. Fine for nRF-only work;
ESP32 and MG24 *companion* builds will fail to link without them.
## Flashing
`west flash` from inside the container only works on a **Linux host** — Docker
Desktop on Windows and macOS cannot pass USB devices through. On Linux, uncomment
the `runArgs` line in [devcontainer.json](devcontainer.json).
Everywhere else, build in the container and flash from the host: the `.uf2`,
`.zip`, `.hex` and `.bin` files in `build/zephyr/` and `firmware/` are on the
bind mount and visible to host tools. Drag-and-drop UF2 flashing needs nothing
installed on the host at all.
## Note on `.vscode/settings.json`
If you have a local (gitignored) `.vscode/settings.json` with a Windows path in
`cmake.sourceDirectory`, it overrides the container setting and points CMake
Tools at a path that does not exist inside the container. Either delete that file
or change the value to `${workspaceFolder}/zephcore`.