Skip to content

fix(build): rebuild_signature omits build_unflags stripping → persistent recompiles for build_unflags projects #970

Description

@zackees

Context

Found while tracing #957. Distinct from #957 (which is the depfile-own-mtime false-stale, fixed separately).

The per-TU .cmdhash rebuild signature has a WRITE-vs-COMPUTE asymmetry around build_unflags:

  • WRITE (after a successful compile): the flags reach compile_source via the default trait compile_cpp/compile_c (crates/fbuild-build/src/compiler.rs:~109-125), which calls apply_compile_unflags(self.cpp_flags(), extra_flags, self.build_unflags()) before compiling. So the signature written to .cmdhash is hashed from flags with build_unflags stripped.
  • COMPUTE (staleness check on rebuild): Esp32Compiler::rebuild_signature (crates/fbuild-build/src/esp32/esp32_compiler.rs:199-220) hashes raw self.c_flags()/self.cpp_flags() with build_unflags NOT applied.

When platformio.ini sets a non-empty build_unflags that strips a real token, WRITE ≠ COMPUTE on every rebuild → the sketch/core TUs recompile persistently (not just once). NightDriverStrip's demo env has empty build_unflags, so it's latent there (which is why #951/#956 measured a clean 2.1 s no-op rebuild) — but any project using build_unflags regresses to full recompiles each build.

The same latent asymmetry exists in the other rebuild_signature overrides that don't apply unflags: the default trait impl (compiler.rs:~161), ch32v_compiler.rs:~194, renesas_compiler.rs:~229.

Fix

Apply apply_compile_unflags(base_flags, extra_flags, self.build_unflags()) inside the signature computation so WRITE and COMPUTE hash the identical post-unflag flag set. Prefer centralizing it (strip unflags inside the shared build_rebuild_signature path, or a shared helper both sides call) so every platform's rebuild_signature is covered rather than fixing per-platform. Note: shipping this shifts all .cmdhash values once → a one-time recompile on the first build after it lands (acceptable, same as any signature-format change).

Acceptance criteria

  • A project with build_unflags = <token> gets a clean no-op rebuild (no recompile) after a warm build.
  • Unit test: rebuild_signature for a compiler with non-empty build_unflags equals the signature the compile path writes.

Decisions

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    Status
    Triage

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions