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

    Fields

    No fields configured for issues without a type.

    Projects

    Status
    Triage

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions