Skip to content

Stale standalone-zccache references in CI / Docker / docs / tests (post-embedded-zccache transition) #855

Description

@zackees

Symptom

fbuild's CI infrastructure, Docker setup, and documentation still reference standalone zccache.exe / zccache-daemon.exe / zccache-fp.exe binaries. This was correct under the pre-2026-06 soldr architecture (where soldr fetched a standalone zccache.exe and used it as RUSTC_WRAPPER), but is stale now:

None of the stale references in fbuild actively break the build today (all four sites are defensively guarded — [ -f ... ] checks, || true, test data that the parser correctly handles, doc strings nobody runs). But:

  • The Docker step silently produces a smaller image than intended (the loop body never copies anything for the zccache entries because the files no longer exist in the upstream tarball).
  • The CI pkill step is dead code masquerading as live housekeeping.
  • The setup.py docstring is documentation that describes a fiction.
  • The test data cements an outdated mental model that will misdirect future debugging.

Smoking guns

1. Dockerfile copies non-existent binaries

File: ci/docker-mac-cross/Dockerfile:68-70

RUN for bin in soldr cargo-chef crgx zccache zccache-daemon zccache-fp; do \
        [ -f "/opt/soldr-bin/$bin" ] && cp "/opt/soldr-bin/$bin" "/usr/local/bin/$bin" && chmod +x "/usr/local/bin/$bin"; \
    done

The [ -f ... ] guard means missing files silently skip, but the intent was to ship zccache zccache-daemon zccache-fp alongside soldr. The pinned SOLDR_VERSION=0.7.59 on line 60 predates the embedded-zccache transition, so the upstream tarball still has those binaries today — but once SOLDR_VERSION gets bumped past the next release (≥ 0.7.72 or wherever the zccache-soldr shim ships), the copy will silently no-op for all three zccache entries.

2. CI workflow kills a daemon that no longer exists

File: .github/workflows/template_build.yml:71-72

- name: Reset zccache daemon after cache warm
  run: pkill -f '[z]ccache-daemon' || true

With embedded zccache, there is no zccache-daemon process running separately. The daemon is soldr-daemon (which embeds zccache), and the lifecycle is owned by soldr — fbuild shouldn't be pkilling it.

3. setup.py docstring describes the legacy architecture

File: setup.py:29

- soldr auto-sets `RUSTC_WRAPPER` to zccache, so rebuilds across `pip
  install .` invocations are incremental + dep-cached.

This is no longer accurate. soldr now sets RUSTC_WRAPPER = <current soldr binary path>; the new dedicated shim is zccache-soldr (not zccache). The user-visible behavior (incremental rebuilds across pip install invocations) is unchanged — only the underlying mechanism. But the doc misleads anyone debugging the wrapper chain.

4. Test data uses legacy zccache.exe wrap shape

File: crates/fbuild-build/src/compile_database/tests/cache_wrapper.rs:28-39

#[test]
fn test_strip_zccache_wrap_mode() {
    let args = vec![
        "C:\\tools\\zccache.exe".to_string(),
        "wrap".to_string(),
        "C:\\tc\\bin\\xtensa-esp32-elf-g++.exe".to_string(),
        ...
    ];

The test isn't broken — strip_cache_wrapper should still be able to parse historical command lines. But hardcoded C:\tools\zccache.exe test data + the wrap subcommand is the legacy pattern. Should be either deleted (if no production code paths still emit this shape) or relabeled with a doc comment explaining it's a backward-compat parse test for a deprecated pattern.

Note: fbuild's core integration is already correct

crates/fbuild-build/Cargo.toml already depends on zccache as a library directly, mirroring soldr's embedded model. The infrastructure-side staleness above is purely vestigial — fbuild has the right architecture; it just has dead code from the old one.

Proposed fix

Four mechanical changes:

  1. ci/docker-mac-cross/Dockerfile: remove zccache zccache-daemon zccache-fp from the for-loop on line 68. Keep soldr cargo-chef crgx.
  2. .github/workflows/template_build.yml: delete the "Reset zccache daemon after cache warm" step (lines 71-72). soldr-daemon's lifecycle is owned by soldr; fbuild should not be pkilling it. If a daemon reset between cache warm and build is genuinely needed, replace with soldr daemon stop (which goes through the IPC shutdown path).
  3. setup.py:29: update the docstring to: soldr auto-sets RUSTC_WRAPPER to itself (or the zccache-soldr shim, per soldr 1081), which talks to soldr-daemon's embedded zccache — rebuilds across "pip install ." invocations are incremental + dep-cached.
  4. crates/fbuild-build/src/compile_database/tests/cache_wrapper.rs:28-39: either delete the test (if no production callers still emit zccache wrap) OR add a // Legacy pre-embedded zccache.exe wrap-mode parse test; retained for backwards-compat parsing only. doc comment above the #[test] so future readers know the shape is intentional historical test data.

Acceptance criteria

  • grep -r 'zccache-daemon\|zccache\.exe\|zccache-fp' --include='*.yml' --include='*.py' --include='Dockerfile*' . returns zero matches in ci/ and .github/workflows/ (test data exception above is documented).
  • Bumping SOLDR_VERSION in the cross-mac Dockerfile to the latest release (post zccache-soldr shim landing) doesn't silently degrade the image's content.
  • setup.py docstring describes the current RUSTC_WRAPPER = soldr / zccache-soldr architecture, not the legacy RUSTC_WRAPPER = zccache.exe one.

References

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