Skip to content

feat(build-info): emit build_info_<env>.json after link (fixes #297)#309

Merged
zackees merged 1 commit into
mainfrom
feat/297-build-info-emitter
May 30, 2026
Merged

feat(build-info): emit build_info_<env>.json after link (fixes #297)#309
zackees merged 1 commit into
mainfrom
feat/297-build-info-emitter

Conversation

@zackees
Copy link
Copy Markdown
Member

@zackees zackees commented May 30, 2026

Summary

Fixes #297. fbuild now emits a PlatformIO-shape build_info_<env>.json next to the project's other build artifacts at the end of a successful sequential build. FastLED's existing ci/compiled_size.py, ci/inspect_binary.py, ci/symbol_analysis_runner.py etc. consume this file unmodified.

Coverage

Wired into pipeline/sequential.rs, which covers AVR, Teensy, RP2040, STM32, NRF52, SAM, Renesas, Apollo3, CH32V, ESP8266. ESP32 uses a different (parallel-compile) pipeline and is intentionally deferred -- same is true for WASM (no firmware.elf). All linkers (including the ESP32 one) already override the new trait accessors, so wiring ESP32 into the emitter in a follow-up PR is a one-call addition.

Schema

{
  "<env>": {
    "prog_path": "...",
    "cc_path": "...", "cxx_path": "...", "ar_path": "...",
    "objcopy_path": "...", "size_path": "...",
    "cc_flags": ["..."], "cxx_flags": ["..."], "link_flags": ["..."],
    "defines": ["..."], "includes": ["..."], "libs": ["..."],
    "platform": "...", "board": "...", "env": "..."
  }
}

Writes both build_info_<env>.json (example-specific) and build_info.json (generic fallback) per FastLED's _find_build_info lookup order.

Linker trait change

Added three optional accessors with None defaults so non-overriding linkers compile unchanged:

fn ar_tool_path(&self) -> Option<&Path> { None }
fn objcopy_tool_path(&self) -> Option<&Path> { None }
fn link_driver_path(&self) -> Option<&Path> { None }

All 10 per-platform linkers override these to return the toolchain binary paths they already hold (gcc_path, ar_path, objcopy_path).

Out of scope

  • FastLED's insert_tool_aliases post-processor (lives on the FastLED side, not in this PR).
  • ESP32 / WASM (different pipelines -- separate follow-up).

Verification

  • soldr cargo check -p fbuild-build -- clean.
  • soldr cargo clippy -p fbuild-build --all-targets -- -D warnings -- clean (only pre-existing MSRV-mismatch warning in clippy.toml unrelated to this change).
  • soldr cargo test -p fbuild-build --lib build_info -- 7 unit tests pass (schema round-trip, dual-file write, env-key wrapping, prog-path priority, define/include extraction).

Summary by CodeRabbit

  • New Features

    • Build system now generates build_info.json metadata files containing toolchain paths, compiler flags, defines, includes, and firmware image information for improved IDE and build tool integration.
  • Chores

    • Extended platform linker implementations to expose tool path information through updated internal APIs.

Review Change Stack

…ixes #297)

Adds a post-link emitter that writes a PlatformIO-compatible
build_info_<env>.json (and the no-example-fallback build_info.json) to
the project directory after a successful sequential build. Outer dict
is keyed by env name (matching `pio project metadata --json-output`);
inner dict carries prog_path plus toolchain binaries (cc/cxx/ar/objcopy
/size) and the compile/link flags fbuild already knows.

This unblocks every FastLED size-check and symbol-analysis workflow
that was silently failing because fbuild compiles succeeded but
downstream _find_build_info() calls couldn't locate the metadata file.
Same shape as `pio project metadata --json-output` so FastLED's
ci/compiled_size.py::_create_board_info accepts it unmodified.

Hooked into pipeline/sequential.rs only -- covers AVR, Teensy, RP2040,
STM32, NRF52, SAM, Renesas, Apollo3, CH32V, ESP8266. ESP32 (different
pipeline) and WASM (no firmware.elf) intentionally deferred to a
follow-up.

Linker trait gains three optional accessors (ar_tool_path,
objcopy_tool_path, link_driver_path) defaulting to None -- per-platform
linkers override to expose the toolchain binaries they already hold.

Closes #297.
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 30, 2026

Caution

Review failed

Pull request was closed or merged during review

📝 Walkthrough

Walkthrough

This pull request implements PlatformIO-compatible build metadata emission for fbuild, enabling downstream CI tooling (size checks, symbol analysis) to consume build configuration without depending on PlatformIO's CLI. The feature extends the Linker trait with optional path accessors, defines a BuildInfo serialization structure with flag extraction and JSON file writing, implements those trait methods across all platform linkers, integrates metadata emission into the build pipeline post-link, and exports the new module.

Changes

Build Metadata Emission and Platform Linker Path Exposure

Layer / File(s) Summary
Linker trait path accessors
crates/fbuild-build/src/linker.rs
The Linker trait gains three new optional methods (ar_tool_path, objcopy_tool_path, link_driver_path) with default None implementations to expose toolchain binary paths through the trait interface.
BuildInfo data structure and JSON emission
crates/fbuild-build/src/build_info.rs
Defines a BuildInfo struct capturing tool paths, compiler/linker flags, extracted -D defines and -I includes from cxx_flags, and platform metadata; implements BuildInfo::new to populate the struct; adds emit_build_info to serialize and write both environment-specific (build_info_<env>.json) and generic (build_info.json) JSON files (serialization errors fail the emission, write errors downgrade to warnings); provides pick_prog_path to select firmware by precedence (.bin, .hex, .elf); includes unit tests covering flag extraction, optional tool path stringification, JSON file presence and structure, and path selection precedence.
Platform linker trait method implementations
crates/fbuild-build/src/avr/avr_linker.rs, crates/fbuild-build/src/ch32v/ch32v_linker.rs, crates/fbuild-build/src/esp32/esp32_linker.rs, crates/fbuild-build/src/esp8266/esp8266_linker.rs, crates/fbuild-build/src/generic_arm/arm_linker.rs, crates/fbuild-build/src/nrf52/nrf52_linker.rs, crates/fbuild-build/src/renesas/renesas_linker.rs, crates/fbuild-build/src/sam/sam_linker.rs, crates/fbuild-build/src/silabs/silabs_linker.rs, crates/fbuild-build/src/teensy/teensy_linker.rs
Each platform linker implements the three new trait methods, exposing stored toolchain paths (ar_path, objcopy_path, gcc_path / link driver) as Some(&Path) references.
Build pipeline metadata emission integration
crates/fbuild-build/src/pipeline/sequential.rs
After the link phase completes, a new "build-info" checkpoint picks an available firmware output path via pick_prog_path, constructs a BuildInfo object populated with resolved toolchain paths (from the Linker trait accessors), effective compiler/linker flags, link overlay flags/libs, platform label, board identifier, and environment name, then calls emit_build_info to write metadata; any metadata emission error is caught and reported via tracing::warn! without failing the overall build.
Public module export
crates/fbuild-build/src/lib.rs
The build_info module is exported publicly, making the BuildInfo struct and emission functions (emit_build_info, pick_prog_path) accessible to external consumers.

🎯 3 (Moderate) | ⏱️ ~25 minutes


🐰 A toolchain unmasked with paths so bright,
Build metadata gleaming, in JSON's light,
From nine boards to countless, no longer we grope,
When CI looks for build_info—we now have the rope!
Post-link, we emit, and the warnings stay soft,
The build succeeds onward, no failures aloft! 🎉

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 79.10% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change: emitting build_info_.json after link phase, directly addressing issue #297.
Linked Issues check ✅ Passed The PR fully implements the core requirements from issue #297: post-link build_info JSON emission with PlatformIO-compatible schema, toolchain path accessors, and integration into the sequential build pipeline.
Out of Scope Changes check ✅ Passed All changes align with issue #297 scope: trait methods for toolchain path exposure, BuildInfo struct for metadata serialization, and post-link emission in sequential pipeline. No unrelated modifications detected.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/297-build-info-emitter

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@zackees zackees merged commit 1a4d661 into main May 30, 2026
85 of 87 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

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

1 participant