Files
twislaandClaude Opus 5.5 07ac7ba457
CI / build (pull_request) Successful in 7m11s
Site / build (pull_request) Successful in 9s
CI: stop rebuilding the framework at every run; a build cache, ccache, and the version out of the compiler flags (#74)
A pull request's firmware step took 358 s: 260 of them rebuilding the
framework that was already in the volume, because the platform decides by
sdkconfig.defaults in the project folder, which is generated and not in git,
so no fresh checkout had it. It is now kept in the volume, inside the
libraries it describes, and copied into the checkout; the platform still
checks its hash against platformio.ini.

The version was a -D on every command line: each commit recompiled
everything, and no cache could help. scripts/version.py now writes one
generated header, read by one file.

PlatformIO's build cache in the volume for pull requests' firmware, ccache
for the host tests (built for coverage, which the build cache can't keep),
the tools in a venv in the volume, and a tag builds its firmware once.
A release still compiles its own sources from nothing.

Measured on fresh copies of the tree: the firmware step 358 s to 27 s (a new
version and one changed file), tests and coverage 49 s to 33 s, a local
rebuild with nothing changed 77 s to 13 s.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EhqxQ49eCju4CzKYNjZzwT
2026-10-07 02:10:34 +02:00

39 lines
1.5 KiB
Python

# Injects the firmware version from `git describe` (semver tags like v0.1.0).
import subprocess
Import("env") # noqa: F821 (provided by PlatformIO)
try:
version = subprocess.check_output(
["git", "describe", "--tags", "--always", "--dirty"], text=True
).strip()
except Exception:
version = "unknown"
# The version goes into one generated header, read by one file (lib/version/src/version.cpp). As a -D
# on every command line it made each new commit recompile everything, and no build cache could help
# (issue #74). Written only when it changes, so an unchanged version rebuilds nothing.
import os
_header = os.path.join(env.subst("$PROJECT_DIR"), "lib", "version", "src", "version_generated.h") # noqa: F821
_text = '#define RORO_VERSION "%s"\n' % version
if not os.path.exists(_header) or open(_header).read() != _text:
open(_header, "w").write(_text)
# Keep every build's ELF, named by version and the first 16 hex digits of its SHA-256 (the core dump
# names the crashed firmware by the same digest), so a crash can be decoded after later builds.
def archive_elf(source, target, env):
import hashlib
import os
import shutil
elf = str(target[0])
digest = hashlib.sha256(open(elf, "rb").read()).hexdigest()[:16]
folder = os.path.join(env.subst("$PROJECT_DIR"), ".pio", "elves")
os.makedirs(folder, exist_ok=True)
shutil.copy(elf, os.path.join(folder, "%s.%s.elf" % (version, digest)))
env.AddPostAction("$BUILD_DIR/${PROGNAME}.elf", archive_elf) # noqa: F821