Skip to content

fbuild deficiency vs PlatformIO: no build_info.json metadata emitter (blocks downstream size/symbol tooling) #297

@zackees

Description

@zackees

Symptom

FastLED's size-check pipeline (ci/ci-check-compiled-size.pyci/compiled_size.py) needs a per-build build_info.json (or build_info_<example>.json) at .build/pio/<board>/. The file is the canonical project-metadata blob produced by:

pio project metadata --json-output

When the build is driven by fbuild (which became the default backend in FastLED's ci-compile.py after commit f215b56b8 ci: make fbuild the default for board builds), no build_info.json is emitted, and every consumer that calls _find_build_info(board) fails with:

FileNotFoundError: build_info.json not found for board '<board>'
(tried build_info_<example>.json and build_info.json in .build/pio/<board> and .build/<board>)

Master CI impact

Every binary-size guard on FastLED master is failing because of this:

  • check_uno_size, check_attiny85, attiny85_binary_size
  • check_teensy30_size, check_teensy31_size, check_teensy32_size, check_teensy35_size, check_teensy36_size, check_teensy41_size, check_teensylc_size
  • check_stm32f103c8_bluepill_size
  • esp32dev_binary_size
  • teensy41_binary_size

(~10 README-visible workflows.) These are pure cascade — the build itself succeeded; only the post-build metadata is missing.

What PlatformIO provides

pio project metadata --json-output returns a single JSON blob keyed by env name with at least:

  • prog_path — absolute path to the linked ELF (or HEX on AVR)
  • cc_path, cxx_path, ar_path, objcopy_path, ... — full toolchain binaries
  • cc_flags, cxx_flags, link_flags, libs, defines, includes
  • extra_flags, srcs, frameworks, platform, board

FastLED's ci/compiler/build_config.py::insert_tool_aliases then injects friendlier aliases on top.

Downstream FastLED scripts that consume this blob:

  • ci/compiled_size.pyprog_path + build dir
  • ci/inspect_binary.py, ci/inspect_elf.py, ci/symbol_analysis_runner.py, ci/optimization_report.py — toolchain paths + ELF path
  • ci/decode_esp32_backtrace.pyobjdump_path, addr2line_path

All of these silently no-op or hard-fail under fbuild today.

Proposed shape for fbuild

Add a post-link emitter that writes <project>/.build/pio/<board>/build_info_<example>.json (mirror PIO's exact layout) populated from values fbuild already knows internally:

  • prog_path → fbuild's link target output path
  • cc_path / cxx_path / ar_path / objcopy_path / objdump_path / addr2line_path / size_path — resolved at toolchain probe time
  • cc_flags / cxx_flags / link_flags / libs / defines / includes — already in the build graph
  • frameworks / platform / board / extra_flags — from BoardConfig
  • srcs — list of compiled units

Wrap that in a key matching the env name (PIO's convention) so the FastLED scripts work without any consumer-side changes.

Suggested entry point: a new EmitBuildInfoJson post-link step in crates/fbuild-build/ (or wherever the artifact-staging code lives), gated on a per-invocation flag like --emit-build-info so non-CI users don't pay the cost.

Workaround being applied immediately to FastLED

While this lands in fbuild, I'm patching FastLED's .github/workflows/build_template_binary_size.yml to force --backend=platformio for the size-check step. That restores PIO's build_info.json emission and reopens all 10 workflows. The workaround can be reverted in one line once fbuild ships the emitter.

Test plan

  • Unit: cargo test -p fbuild-<crate> covering the new emitter (write a JSON blob to a tempdir, assert keys present + parseable, assert it deserializes via the same struct PIO's output does).
  • Integration: pop fastled's PIO workaround, rebuild, confirm .build/pio/<board>/build_info_<example>.json lands and ci/compiled_size.py succeeds.

Filed during a coordinated CI-green sweep on FastLED master. Companion unblocking PR coming to FastLED in parallel.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions