Skip to content

perf(zccache) Phase 4 stage 2: embedded mandatory — delete FBUILD_ZCCACHE_EMBEDDED + wrapper fallback #800

Description

@zackees

Follow-up to #789 (closed by #798).

Phase 4 stage 1 (#793) made the embedded ZccacheService the
default but kept the wrapper-mode code path alive as a safety net,
selectable via FBUILD_ZCCACHE_EMBEDDED=0. This issue is the
stage 2 cleanup: embedded is now MANDATORY, the opt-out is
deleted, every wrapper-mode escape hatch is removed.

Goal

After this PR:

  • FBUILD_ZCCACHE_EMBEDDED env var does nothing — both =0 and
    =1 are ignored. (Eventually a tracing::warn! if seen, then
    removed.)
  • CompileBackend::Wrapped variant gone. CompileBackend becomes
    a unit struct or a typedef for the embedded service handle.
  • --no-default-features no longer drops zccache — the
    embedded Cargo feature is gone (it's just "compiled in,
    always").
  • The managed zccache.exe / zccache-daemon.exe / zccache-fp.exe
    binary download path (managed_zccache.rs) is deleted.
  • ~/.fbuild/<mode>/bin/zccache-* is no longer a directory fbuild
    creates.

Files to delete

  • crates/fbuild-build/src/managed_zccache.rs (whole file).
  • The compile_source wrapper-mode arms in
    crates/fbuild-build/src/compiler.rs (~lines 631–681 — the
    if cfg!(windows) { … wrap_args … } else { … } block + the
    run_command + retry-on-stale-daemon dance).
  • wrap_args, find_zccache, discover_env_zccache,
    find_zccache_in_venv, ensure_running, stop,
    output_has_stale_daemon_error, and the ZCCACHE_PATH cache in
    crates/fbuild-build/src/zccache.rs.
  • check_fingerprint / mark_fingerprint_success lose their
    wrapper-mode fallback bodies (the embedded path becomes the only
    path).
  • FBUILD_NO_ZCCACHE and FBUILD_ZCCACHE_BIN env-var handling
    everywhere.
  • MANAGED_ZCCACHE_VERSION references in pyproject.toml, in
    CI release matrix, and in .github/scripts/.
  • The compiler_cache: Option<&Path> parameter on
    compile_source, Compiler::compile_one, and every per-platform
    compiler that threads it (avr, esp32, esp8266, rp2040, stm32,
    teensy, nrf52, nxplpc, sam, silabs, apollo3, ch32v, renesas,
    generic_arm).
  • The wrapper-mode path-normalization helpers in
    crates/fbuild-build/src/zccache.rs (compile_cwd_from_output,
    path_arg_for_compile_cwd, normalize_flags_for_compile_cwd,
    strip_unc_prefix, flag_takes_path_argument,
    split_joined_path_flag) MAY be retained if the embedded
    service needs them at the call boundary. Decide per-helper.

Files to update

  • crates/fbuild-build/Cargo.toml — delete the embedded feature
    flag; promote zccache = { git = …, optional = true } to an
    unconditional dep.
  • crates/fbuild-daemon/Cargo.toml — drop the embedded feature
    propagation.
  • crates/fbuild-build/src/compile_backend.rs — collapse
    CompileBackend to a thin wrapper around
    Arc<FbuildZccacheService>. Rename from_env to start since
    there's no env-var branching left. Delete EmbeddedServiceError:: Start fallback warnings — failure becomes a hard error (the
    daemon refuses to start if zccache can't).
  • crates/fbuild-build/src/zccache_embedded.rs — keep, but rename
    FbuildZccacheService::start to clarify it's the only entry
    point. Inline the compile_blocking call site into
    compile_source since there's no longer a wrapper alternative
    to switch on.
  • crates/fbuild-daemon/src/main.rsinstall_global becomes
    unconditional; remove the fallback log lines.
  • crates/fbuild-daemon/src/context.rscompile_backend field
    becomes Arc<FbuildZccacheService> instead of an enum.
  • crates/fbuild-build/README.md — replace the "Two backends" section
    with a "How zccache is wired" section. No more opt-out section,
    no more --no-default-features advice.
  • CLAUDE.md — drop every mention of MANAGED_ZCCACHE_VERSION
    and the lockstep-bump workflow.
  • docs/RELEASING.md — same.

Issues to close in the same PR

  • FastLED/fbuild#32
    — the rationale for the intentionally-detached zccache start
    spawn (so the wrapper daemon could outlive fbuild-daemon) is
    moot once ensure_running is gone. The cache is now part of
    the fbuild process; it dies with the fbuild process. Add
    Closes #32 to the PR body.

Acceptance

  • cargo check --workspace --all-targets clean. No
    --features fbuild-build/embedded invocation needed
    anywhere (the feature is gone).
  • cargo clippy --workspace --all-targets -- -D warnings clean.
  • uv run test --full green on Linux, macOS, Windows.
  • grep -rn 'FBUILD_ZCCACHE_EMBEDDED\|FBUILD_NO_ZCCACHE\|FBUILD_ZCCACHE_BIN\|MANAGED_ZCCACHE_VERSION\|managed_zccache\|wrap_args\|ensure_running' crates/ docs/ CLAUDE.md
    returns no hits (except possibly in a release note / CHANGELOG).
  • ~/.fbuild/<mode>/bin/zccache-* is NOT created on a clean
    run against a fresh ~/.fbuild/.
  • Process snapshot during fbuild build tests/platform/uno
    shows zero zccache.exe / zccache-daemon.exe /
    zccache-fp.exe children. No wrapper binary spawn anywhere.
  • crates/fbuild-build/Cargo.toml has no embedded feature
    entry. zccache dep is unconditional.
  • Daemon teardown hardening: process containment + socket lingering + console events #32 closed in the same PR.

Risks / sequencing

  • One release cycle of soak time on the stage-1 default flip
    (perf(zccache) Phase 4: flip embedded to default, retire managed wrapper #793) before this PR.
    Stage 1 shipped in feat(zccache): omnibus migration — embedded backend as default (#789 Phases 1-4) #798. Land this
    cleanup only after a release where stage-1's default has been
    exercised in the wild without regressions. The PR is irreversible
    in practice (the wrapper code is gone, not gated off), so the
    validation gate matters.
  • Cross-platform CI must light up on the stage-2 PR. The
    embedded service's cache directory creation, file locking, and
    path-normalization behavior all need to work on Linux + macOS +
    Windows without the wrapper-mode safety net.
  • Any consumer of find_zccache outside fbuild-build itself
    none today AFAIK, but worth a final grep before deleting.

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