STAR
Cal STAR — firmware, DAQ server, and engine design
Loading...
Searching...
No Matches
reproducible_build Namespace Reference

Functions

 _find_repo_root (start)
 _add (old, new)

Variables

 _MARKER = Path("firmware/tools/reproducible_build.py")
 REPO_ROOT = _find_repo_root(Path(env.subst("$PROJECT_DIR")).resolve())
list _MAPPINGS
list flags = []
 seen = set()
 _packages = env.subst("$PROJECT_PACKAGES_DIR")
 _pkgdir = Path(_packages)
 CCFLAGS

Detailed Description

Make the built image independent of where it was built.

PlatformIO extra script. Wire it in with, in a project's platformio.ini:

    extra_scripts = pre:../../tools/reproducible_build.py

Why this exists
---------------
Every board reports a SHA-256 of its own firmware in its heartbeat, and CI keeps
a registry mapping that digest back to the commit that produced it (see
firmware/tools/which_firmware.py). That only works if the same source produces
the same bytes on every machine.

It did not. `ESP_ERROR_CHECK`, `assert` and the ESP log macros all expand
`__FILE__`, and the compiler sees absolute paths, so the image carried strings
like

    /home/aidan/.platformio/packages/framework-arduinoespressif32/cores/esp32/esp32-hal-spi.c
    /home/aidan/STAR-daq/firmware/Hotfire_Code/common/SensorHotfireCore.h

baked into the hashed bytes -- the username, the home directory and the checkout
path. The same commit built by two people, or by CI, produced three different
digests, so the digest identified the machine rather than the firmware.

`-ffile-prefix-map=OLD=NEW` rewrites those paths at compile time (it covers
`__FILE__` and the debug info both). GCC compares OLD as a literal prefix of the
path it has already normalised, so the mapping has to be an absolute, canonical
path -- which is why this is a script and not a line of `build_flags`: the header
that leaks sits at `-I../common`, outside `$PROJECT_DIR`, and no interpolation
available in platformio.ini can name its directory without a `..` that then
fails to match.

Keep the replacement names stable. Changing `/star` or `/pio` changes every
digest in the registry.

Function Documentation

◆ _add()

reproducible_build._add ( old,
new )
protected

Definition at line 70 of file reproducible_build.py.

References _add().

Referenced by _add().

◆ _find_repo_root()

reproducible_build._find_repo_root ( start)
protected

Definition at line 47 of file reproducible_build.py.

Variable Documentation

◆ _MAPPINGS

list reproducible_build._MAPPINGS
protected
Initial value:
1= [
2 (env.subst("$PROJECT_CORE_DIR"), "/piocore"), # noqa: F821
3 (env.subst("$PROJECT_PACKAGES_DIR"), "/pio"), # noqa: F821
4 (str(REPO_ROOT) if REPO_ROOT else "", "/star"),
5]

Definition at line 60 of file reproducible_build.py.

◆ _MARKER

reproducible_build._MARKER = Path("firmware/tools/reproducible_build.py")
protected

Definition at line 44 of file reproducible_build.py.

◆ _packages

reproducible_build._packages = env.subst("$PROJECT_PACKAGES_DIR")
protected

Definition at line 96 of file reproducible_build.py.

◆ _pkgdir

reproducible_build._pkgdir = Path(_packages)
protected

Definition at line 98 of file reproducible_build.py.

◆ CCFLAGS

reproducible_build.CCFLAGS

Definition at line 108 of file reproducible_build.py.

◆ flags

list reproducible_build.flags = []

Definition at line 66 of file reproducible_build.py.

◆ REPO_ROOT

reproducible_build.REPO_ROOT = _find_repo_root(Path(env.subst("$PROJECT_DIR")).resolve())

Definition at line 54 of file reproducible_build.py.

◆ seen

reproducible_build.seen = set()

Definition at line 67 of file reproducible_build.py.