Release CI lost -C target-cpu=x86-64-v3: !17 made it opt-in via RUSTFLAGS and no workflow sets it #20

Closed
opened 2026-08-26 04:39:44 +02:00 by pbwraith · 1 comment
Owner

What changed

!17 (#16) merged today. It makes the x86_64 build portable by removing the
forced -C target-cpu=x86-64-v3 from .cargo/config.toml and making it opt-in
via RUSTFLAGS. That was necessary and correct -- on a pre-AVX2 host the flag
miscompiles dependency build scripts (num-traits' build script SIGABRTs on a
648518346341351440-byte allocation), so the review box could not build the repo
at all.

The gap it opens

RUSTFLAGS is now the only way to get the optimised target back, and nothing
sets it
. Measured on origin/issue-16 @ 800495c, before merge:

$ grep -rc RUSTFLAGS .github/workflows/*.yml
.github/workflows/build.yml:0
.github/workflows/lint.yml:0
.github/workflows/sec.yml:0

So every release binary now compiles at the Rust default x86_64 baseline
instead of x86-64-v3. The affected invocations in
.github/workflows/build.yml are:

line job target
72 linux x86_64-unknown-linux-gnu
120 windows x86_64-pc-windows-msvc

Both are published as release artifacts (build.yml:293, :295 push
gopher64-linux-x86_64 and gopher64-windows-x86_64.exe to itch via butler).

This matters more than usual here because gopher64 is an emulator: the JIT and
the RSP/RDP paths are per-frame hot code, and AVX2/BMI2 is exactly the kind of
win that was being taken. Nobody will see a build failure -- the binaries just
get slower, silently.

Scope

Restore x86-64-v3 for the published x86_64 release builds only, by setting
RUSTFLAGS on those two jobs (or on the two matrix entries). Do not put it back
in .cargo/config.toml -- that is the thing that broke the review box, and
!17's portable default is deliberate.

Note the trap !17 documents at .cargo/config.toml:31: RUSTFLAGS REPLACES
the config's rustflags rather than appending
. The Windows x86_64 entry
currently relies on
[target.'cfg(target_os = "windows")'] rustflags = ["-C", "link-arg=/STACK:8388608"],
so a bare RUSTFLAGS="-C target-cpu=x86-64-v3" on that job would drop the 8 MB
stack link-arg
. Carry it across:

RUSTFLAGS: "-C target-cpu=x86-64-v3 -C link-arg=/STACK:8388608"

The Linux x86_64 entry has no config rustflags to preserve, so it takes the flag
alone.

Explicitly OUT of scope

  • Changing .cargo/config.toml back in any way.
  • The aarch64 / macOS entries -- they set their own target-cpu and are
    untouched by !17.
  • Choosing a different baseline (v2 vs v3) for the default build. If you
    want the default raised to x86-64-v2, that is a separate decision; note the
    .cargo/config.toml:28-29 comment currently claims the portable baseline
    "only requires x86-64-v2 (SSE4.2)" while the config actually delivers the
    plain x86-64 (v1) default, since it sets no x86_64 rustflags at all. Worth
    making that comment true in the same pass, but it is a comment fix, not a
    build change.

Acceptance criteria

  1. grep -rc RUSTFLAGS .github/workflows/build.yml returns a non-zero count.
  2. The linux and windows x86_64 jobs both build with
    -C target-cpu=x86-64-v3, and the windows one still carries
    -C link-arg=/STACK:8388608.
  3. .cargo/config.toml is byte-identical to its post-!17 state
    (git diff origin/main -- .cargo/config.toml is empty).
  4. No other job gains RUSTFLAGS.
## What changed `!17` (#16) merged today. It makes the x86_64 build portable by removing the forced `-C target-cpu=x86-64-v3` from `.cargo/config.toml` and making it opt-in via `RUSTFLAGS`. That was necessary and correct -- on a pre-AVX2 host the flag miscompiles dependency *build scripts* (`num-traits`' build script SIGABRTs on a 648518346341351440-byte allocation), so the review box could not build the repo at all. ## The gap it opens `RUSTFLAGS` is now the only way to get the optimised target back, and **nothing sets it**. Measured on `origin/issue-16` @ `800495c`, before merge: ``` $ grep -rc RUSTFLAGS .github/workflows/*.yml .github/workflows/build.yml:0 .github/workflows/lint.yml:0 .github/workflows/sec.yml:0 ``` So every release binary now compiles at the Rust default x86_64 baseline instead of `x86-64-v3`. The affected invocations in `.github/workflows/build.yml` are: | line | job | target | |---|---|---| | 72 | linux | `x86_64-unknown-linux-gnu` | | 120 | windows | `x86_64-pc-windows-msvc` | Both are published as release artifacts (`build.yml:293`, `:295` push `gopher64-linux-x86_64` and `gopher64-windows-x86_64.exe` to itch via butler). This matters more than usual here because gopher64 is an emulator: the JIT and the RSP/RDP paths are per-frame hot code, and AVX2/BMI2 is exactly the kind of win that was being taken. Nobody will see a build failure -- the binaries just get slower, silently. ## Scope Restore `x86-64-v3` for the **published x86_64 release builds only**, by setting `RUSTFLAGS` on those two jobs (or on the two matrix entries). Do not put it back in `.cargo/config.toml` -- that is the thing that broke the review box, and `!17`'s portable default is deliberate. Note the trap `!17` documents at `.cargo/config.toml:31`: **`RUSTFLAGS` REPLACES the config's rustflags rather than appending**. The Windows x86_64 entry currently relies on `[target.'cfg(target_os = "windows")'] rustflags = ["-C", "link-arg=/STACK:8388608"]`, so a bare `RUSTFLAGS="-C target-cpu=x86-64-v3"` on that job would **drop the 8 MB stack link-arg**. Carry it across: ```yaml RUSTFLAGS: "-C target-cpu=x86-64-v3 -C link-arg=/STACK:8388608" ``` The Linux x86_64 entry has no config rustflags to preserve, so it takes the flag alone. ## Explicitly OUT of scope - Changing `.cargo/config.toml` back in any way. - The aarch64 / macOS entries -- they set their own `target-cpu` and are untouched by `!17`. - Choosing a different baseline (`v2` vs `v3`) for the default build. If you want the default raised to `x86-64-v2`, that is a separate decision; note the `.cargo/config.toml:28-29` comment currently claims the portable baseline "only requires x86-64-v2 (SSE4.2)" while the config actually delivers the plain `x86-64` (v1) default, since it sets no x86_64 rustflags at all. Worth making that comment true in the same pass, but it is a comment fix, not a build change. ## Acceptance criteria 1. `grep -rc RUSTFLAGS .github/workflows/build.yml` returns a non-zero count. 2. The linux and windows x86_64 jobs both build with `-C target-cpu=x86-64-v3`, and the windows one still carries `-C link-arg=/STACK:8388608`. 3. `.cargo/config.toml` is byte-identical to its post-`!17` state (`git diff origin/main -- .cargo/config.toml` is empty). 4. No other job gains `RUSTFLAGS`.
pbwraith added the
p2
rust
labels 2026-08-26 04:39:44 +02:00
pbwraith added the
in-progress
label 2026-08-26 04:48:12 +02:00
pbwraith added
in-review
and removed
in-progress
labels 2026-08-26 04:53:31 +02:00
Author
Owner

[worker] lane3 implemented — PR #22 (branch issue-20, base main).

Commit: f56f42a "ci(build): restore -C target-cpu=x86-64-v3 on published x86_64 builds" (1 file, +17).

Per acceptance criteria:

  1. grep -rc RUSTFLAGS .github/workflows/build.yml → 9 (non-zero); lint.yml and sec.yml stay 0.
  2. linux x86_64 row: RUSTFLAGS=-C target-cpu=x86-64-v3; windows x86_64 row: RUSTFLAGS=-C target-cpu=x86-64-v3 -C link-arg=/STACK:8388608 (stack arg carried across because RUSTFLAGS replaces config rustflags).
  3. .cargo/config.toml byte-identical to origin/main (git diff origin/main -- .cargo/config.toml empty).
  4. No other job gains RUSTFLAGS — flags are applied by an if: matrix.target == 'x86_64-...' step writing $GITHUB_ENV, so the aarch64 rows never receive any RUSTFLAGS env; macOS/android jobs untouched.

Why the if-step instead of env: RUSTFLAGS: ${{ matrix.rustflags }}: empirically verified with cargo 1.98.0 that an empty-string RUSTFLAGS (what an undefined matrix key evaluates to) REPLACES config rustflags — it would silently drop the aarch64 rows' -fuse-ld=lld / /STACK:8388608 link-args.

Verification: flag strings passed end-to-end through the toolchain (RUSTFLAGS="-C target-cpu=x86-64-v3" cargo build -v → rustc line carries -C target-cpu=x86-64-v3; rustc -C target-cpu=x86-64-v3 -C link-arg=/STACK:8388608 --print cfg parses clean). git diff --check clean; workflow YAML parses.

[worker] lane3 implemented — PR #22 (branch `issue-20`, base `main`). Commit: `f56f42a` "ci(build): restore -C target-cpu=x86-64-v3 on published x86_64 builds" (1 file, +17). Per acceptance criteria: 1. `grep -rc RUSTFLAGS .github/workflows/build.yml` → **9** (non-zero); lint.yml and sec.yml stay 0. 2. linux x86_64 row: `RUSTFLAGS=-C target-cpu=x86-64-v3`; windows x86_64 row: `RUSTFLAGS=-C target-cpu=x86-64-v3 -C link-arg=/STACK:8388608` (stack arg carried across because RUSTFLAGS replaces config rustflags). 3. `.cargo/config.toml` byte-identical to origin/main (`git diff origin/main -- .cargo/config.toml` empty). 4. No other job gains RUSTFLAGS — flags are applied by an `if: matrix.target == 'x86_64-...'` step writing `$GITHUB_ENV`, so the aarch64 rows never receive any RUSTFLAGS env; macOS/android jobs untouched. Why the if-step instead of `env: RUSTFLAGS: ${{ matrix.rustflags }}`: empirically verified with cargo 1.98.0 that an empty-string RUSTFLAGS (what an undefined matrix key evaluates to) REPLACES config rustflags — it would silently drop the aarch64 rows' `-fuse-ld=lld` / `/STACK:8388608` link-args. Verification: flag strings passed end-to-end through the toolchain (`RUSTFLAGS="-C target-cpu=x86-64-v3" cargo build -v` → rustc line carries `-C target-cpu=x86-64-v3`; `rustc -C target-cpu=x86-64-v3 -C link-arg=/STACK:8388608 --print cfg` parses clean). `git diff --check` clean; workflow YAML parses.
This repo is archived. You cannot comment on issues.
No Milestone
No project
No Assignees
1 Participants
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: pbwraith/gopher64-netplay#20
No description provided.