cmux-tui: a new build stamp no longer recompiles cmux-remote or acpmux

Closed
LA
6d ago
+185-51

Summary

This is the follow-up to #21980. #21980 is merged into feat-cmux-next. This branch is rebased on feat-cmux-next, so the diff has only the change of this PR (3 commits).

When the Linux build pool builds a new stamp, cmux-remote and acpmux no longer recompile.

  • cmux-remote: ssh_bootstrap.rs read CMUX_TUI_DISTRIBUTION_VERSION and CMUX_TUI_NPM_BOOTSTRAP_VERSION with option_env!. The pool sets the first to 0.0.0-r2.sha-<stamp>. The two constants move to the binary (cmux-tui/src/distribution.rs) with the same values and the same fallback (CARGO_PKG_VERSION). SshBootstrapConfig::defaults now takes them as arguments, as it already takes build_identity. The cmux-remote tests pass the same values.
  • acpmux: Its build script reran on every new CMUX_GIT_SHORT_SHA and SOURCE_DATE_EPOCH (the pool sets both for each stamp) and on every commit. A rerun recompiles every target of the package (17 s).
    • The script moves to a new leaf crate, acpmux-build-id. The logic does not change. The git calls still run in the acpmux crate directory, and the dirty check and the rerun-if-changed paths are still acpmux's.
    • acpmux reads the id through hub::build(). With its default build-id feature (the standalone acpmux binary and the acpmux tests), the stamped value is the default.
    • cmux-tui uses default-features = false, depends on acpmux-build-id itself, and installs the same value in main(), next to install_build_stamp.
    • acpmux --version uses hub::version_line(), which gives the same text.
  • cmux-build-identity: No change.
    • In the pool, its build script takes less than 0.05 s for each stamp, because the pool sets CMUX_TUI_BUILD_TIME. When CMUX_TUI_BUILD_COMMIT is set, the script already skips the git source walk.
    • The 8.8 s in the #21980 measurement came from the proof setup and not from the pool. My fake stamp aaaa… is not in the Testbox repository, and that repository is a partial clone (blob:none). So git log -1 --format=%ct <stamp> in build_time() started a lazy fetch from GitHub. With a real local commit, or with CMUX_TUI_BUILD_TIME set, the script ran in 0.00 s.

Proof (Blacksmith Testbox, 32 vCPU)

Command: cargo build -v --timings -p cmux-tui --bin cmux-tui --locked. The settings are the pool Linux twin settings (CARGO_INCREMENTAL=0, CARGO_PROFILE_DEV_DEBUG=0). Every stamp variable follows the stamp, as in build-cmux-tui-source.sh: CMUX_TUI_BUILD_COMMIT, CMUX_TUI_GHOSTTY_COMMIT, CMUX_TUI_DISTRIBUTION_VERSION=0.0.0-r2.sha-<stamp>, CMUX_GIT_SHORT_SHA, SOURCE_DATE_EPOCH, CMUX_TUI_BUILD_TIME. The stamps are A=aaaa… and B=bbbb….

treestamp changewallrecompiled
before (#21980 head dc6132488bac)A to B35.1 sacpmux 17.2 s, cmux-remote 9.9 s, cmux-tui 20.4 s
beforeB to A35.2 sacpmux 17.3 s, cmux-remote 10.3 s, cmux-tui 20.5 s
after (a501c02ed5bb)A to B21.0 scmux-tui 20.1 s (acpmux-build-id and cmux-build-identity less than 0.05 s each)
afterB to A20.6 scmux-tui 19.6 s

Together with #21980, a new stamp went from about 52 s to about 21 s on the twin. The feat-cmux-next base before #21980 took 51.5 s and 52.5 s.

Readers, before and after, with the same stamp. All values are identical:

--version:          cmux 0.1.0 (aaaa…; ghostty cccc…)
acpmux --version:   acpmux 0.1.0 (aaaaaaaaa 2026-10-14)
remote-probe --json: distribution_version=0.0.0-r2.sha-aaaa…, npm_bootstrap_version=None, build_identity=aaaa…, build_time=1792000000
identify / ping:    build_commit=aaaa…, ghostty_commit=cccc…, build_id=aaaa…

For B, every reader reports bbbb…, bbbbbbbbb 2026-10-15 and 1792100000.

Binary differences between A and B (equal sizes). The sections with differences are the same before and after this PR, so this PR adds no new kind of difference:

  • before: .rodata 7407, .text 3897, .rela.dyn 839, .symtab 116, .note.gnu.build-id 20 bytes
  • after: .rodata 7337, .text 3910, .rela.dyn 845, .symtab 114, .note.gnu.build-id 20 bytes

These numbers are larger than the 380 bytes in #21980. Here the pool stamps change string lengths (distribution version, short SHA, date), so code and relocations that refer to .rodata move.

Tests (Testbox)

  • cargo fmt --check for acpmux, acpmux-build-id, cmux-remote and cmux-tui: ok
  • cargo test -p cmux-remote --test ssh_cross_platform_bootstrap: 17 passed (bootstrap with the passed distribution version)
  • cargo test -p cmux-tui --test cli remote_update_need: 5 passed
  • cargo clippy --all-targets -D warnings for acpmux, acpmux-build-id, cmux-remote and cmux-tui: ok. Also -p acpmux --no-default-features: ok.

I ran the timing proof at a501c02ed5bb. The 2 later commits are a rustfmt change and one path qualification.

No new tests. Cargo.lock gains the acpmux-build-id package (path crate, no new external dependency).

🤖 Generated with Claude Code


View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need.


Summary by cubic

A new build stamp from the Linux pool now recompiles only cmux-tui; cmux-remote, acpmux, and cmux-tui-core no longer do. This cuts the per-stamp rebuild from about 52 s to about 21 s.

  • Stamped distribution versions move to the binary (distribution.rs) and pass into SshBootstrapConfig::defaults; the build and Ghostty commits install into cmux-tui-core at the top of main via install_build_stamp.
  • acpmux's build script moves to the leaf crate acpmux-build-id; cmux-tui depends on acpmux without its default build-id feature and installs the same value through hub::install_build, so a new stamp recompiles only the tiny leaf crate.
  • Every entry point that serves identify or ping must call install_build_stamp; a process that doesn't reports build_commit: null as before. --version, acpmux --version, and remote-probe --json output are unchanged.