Skip to content

Build-at-install fallback for evsieve is broken: Debian 12's packaged rustc (1.63) can't compile the pinned source #196

Description

@aradanmn

Found during #126d (Deck-validating the prebuilt-fetch and forced-fallback paths for v1.2.4)

Path A (prebuilt fetch, the common case) is fully validated and working
confirmed against the real v1.2.4 release: install_evsieve() fetched
evsieve-x86_64-linux + .sha256 + .stamp from
releases/latest/download, verified the pin/checksum, ran
_evsieve_host_verify, and installed. EVSIEVE_INSTALL_STATUS=installed-prebuilt,
binary reports 1.4.0. No issue there.

Path B (build-at-install, the fallback) does not currently work at all
on a genuinely fresh mcss-evsieve-build distrobox (purged and recreated
from a freshly-pulled debian:12 image, to rule out stale-container state):

rustc 1.63.0
cargo 1.65.0

cargo build --release on the pinned evsieve source
(ebd7efe1ee902e70c5943b65a2bf44b9a3c31eb8) fails with >100 errors, e.g.:

error: extern block cannot be declared unsafe
   --> src/bindings/libevdev.rs:121:1
    |
121 | unsafe extern "C" {
    | ^^^^^^
...
error[E0433]: failed to resolve: could not find `offset_of` in `mem`
  --> src/bindings/libevdev.rs:80:56
...
error[E0658]: `let...else` statements are unstable
  --> src/arguments/capability.rs:72:17
...
error[E0658]: use of unstable library feature 'int_roundings'
  --> src/arguments/oscillate.rs:54:40

src/bindings/libevdev.rs is checked into the pinned commit itself
(confirmed via git show <pin>:src/bindings/libevdev.rs — it's a
pre-generated file via evsieve's own generate_bindings.sh, not something
our build.rs invocation regenerates), and it already uses unsafe extern "C" { } blocks. That syntax needs a materially newer rustc than Debian
12 bookworm ships via apt. let...else and int_roundings::div_ceil are
also gated on a newer edition/toolchain than 1.63.

This means the fallback has been broken since it was written (#38 D4,
2026-07-19) — EVSIEVE_PINNED_COMMIT has never changed, so this isn't a
regression from today's #126 work. It went unnoticed because
_evsieve_build_in_box redirects the whole cargo build invocation to
/dev/null 2>&1 (only the wrapping print_progress lines are visible), so
a real failure here has never been distinguishable from success in any
install log without redirecting stderr manually, as done here.

Why this doesn't block v1.2.4

With #126 shipped, install_evsieve() tries the prebuilt release asset
FIRST and only reaches this path if that fails (network outage, checksum
mismatch, or a future pin drift). Every real install today uses Path A.
The degrade behavior when Path B also fails is correct and fail-open
exactly as designed: EVSIEVE_INSTALL_STATUS=degraded-build-failed, a
clear print_warning, no partial/corrupt binary, and the rest of the
install (Minecraft, Steam integration) continues unaffected. Confirmed
this on hardware too — nothing broke downstream of the failed build.

What needs fixing

The build-at-install path needs a toolchain that can actually compile the
pin — options:

  1. Install Rust via rustup inside the box (a specific stable channel)
    instead of apt-get install cargo, matching what release.yml's CI job
    already does via dtolnay/rust-toolchain@stable. Costs an extra
    download during the (already slow, multi-minute) fallback path, but
    that path is meant to be a last resort now, not the common case.
  2. Alternative: vendor/pin an older evsieve commit whose checked-in
    bindings predate the modern syntax — rejected on sight, since it would
    mean shipping two different actual evsieve versions between the prebuilt
    and fallback paths (PRINCIPLES feat: Add Microsoft account OAuth setup during installation #9, one encoding).

(1) is the obvious fix. Not fixing tonight — filing for backlog since it's
real but non-blocking.

Repro

On the Deck, with the box removed (distrobox rm -f mcss-evsieve-build,
or after uninstall-minecraft-splitscreen.sh --purge):

distrobox enter --name mcss-evsieve-build -- sh -c 'cd <pinned evsieve checkout> && cargo build --release'

Related

#126 (prebuilt binary — masks this for all real installs), #38 D4 (original
build-at-install design), #124 (the sudo/TTY hang in this same box, already
fixed).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions