Runnable build gate on the review box: portable config + documented gate script (#16)
Some checks failed
Rust / build-linux (linux-aarch64, ARM64, ubuntu-24.04-arm, aarch64-unknown-linux-gnu) (push) Waiting to run
Rust / build-windows (windows-aarch64, woa64, windows-11-arm, aarch64-pc-windows-msvc) (push) Waiting to run
Rust / build-windows (windows-x86_64, win64, windows-2025, x86_64-pc-windows-msvc) (push) Waiting to run
Rust / build-macos (macos-aarch64, ARM64, aarch64-apple-darwin) (push) Waiting to run
Rust / Collect release artifacts (push) Blocked by required conditions
Rust / build-linux (linux-x86_64, X64, ubuntu-24.04, x86_64-unknown-linux-gnu) (push) Failing after 7s
Rust / build-android (29.0.14206865, ubuntu-24.04, 33) (push) Failing after 4s
Rust-lint / lint-linux (push) Failing after 23s
Some checks failed
Rust / build-linux (linux-aarch64, ARM64, ubuntu-24.04-arm, aarch64-unknown-linux-gnu) (push) Waiting to run
Rust / build-windows (windows-aarch64, woa64, windows-11-arm, aarch64-pc-windows-msvc) (push) Waiting to run
Rust / build-windows (windows-x86_64, win64, windows-2025, x86_64-pc-windows-msvc) (push) Waiting to run
Rust / build-macos (macos-aarch64, ARM64, aarch64-apple-darwin) (push) Waiting to run
Rust / Collect release artifacts (push) Blocked by required conditions
Rust / build-linux (linux-x86_64, X64, ubuntu-24.04, x86_64-unknown-linux-gnu) (push) Failing after 7s
Rust / build-android (29.0.14206865, ubuntu-24.04, 33) (push) Failing after 4s
Rust-lint / lint-linux (push) Failing after 23s
This commit is contained in:
commit
8a46ac58a2
@ -1,3 +1,20 @@
|
||||
# Build configuration for gopher64-netplay.
|
||||
#
|
||||
# Portability note (issue #16): the DEFAULT build must run on the review
|
||||
# box (Intel i7-2600K, Sandy Bridge 2011 = x86-64-v2). Two upstream
|
||||
# defaults broke it:
|
||||
#
|
||||
# 1. `-C target-cpu=x86-64-v3` (requires AVX2/BMI2, Haswell 2013+)
|
||||
# miscompiles BUILD SCRIPTS on pre-AVX2 hosts: garbage allocation
|
||||
# sizes and SIGABRT (observed: num-traits' build script aborting on
|
||||
# a 648518346341351440-byte allocation). It is now opt-in via
|
||||
# RUSTFLAGS for capable hardware; the default build is portable.
|
||||
# 2. `AR=llvm-ar` forced an LLVM archiver that is not in the provisioned
|
||||
# root; dropped — the platform `ar` archives clang objects fine.
|
||||
# `CC=clang`/`CXX=clang++` are retained (build.rs needs clang for
|
||||
# `-flto=thin`) and resolved through PATH; see scripts/gate.sh for the
|
||||
# review box's clang-18 wiring.
|
||||
|
||||
[target.'cfg(all(target_arch = "aarch64", target_os = "linux"))']
|
||||
rustflags = ["-C", "link-arg=-fuse-ld=lld"]
|
||||
|
||||
@ -7,21 +24,31 @@ linker = "rust-lld"
|
||||
[target.'cfg(target_os = "windows")']
|
||||
rustflags = ["-C", "link-arg=/STACK:8388608"]
|
||||
|
||||
[target.'cfg(target_arch = "x86_64")']
|
||||
rustflags = ["-C", "target-cpu=x86-64-v3"]
|
||||
# No x86_64 rustflags by default: the portable baseline only requires
|
||||
# x86-64-v2 (SSE4.2). On AVX2-capable hardware, opt into the optimised
|
||||
# target with:
|
||||
# RUSTFLAGS="-C target-cpu=x86-64-v3" cargo build --release
|
||||
# (RUSTFLAGS REPLACES the config's rustflags, so carry any other flags.)
|
||||
|
||||
[target.'cfg(all(target_arch = "aarch64", target_os = "macos"))']
|
||||
rustflags = [
|
||||
"-C", "target-cpu=apple-m1",
|
||||
"-C", "link-arg=-headerpad_max_install_names"
|
||||
"-C", "link-arg=-headerpad_max_install_names",
|
||||
]
|
||||
|
||||
[target.'cfg(all(target_arch = "aarch64", not(target_os = "macos")))']
|
||||
rustflags = ["-C", "target-cpu=cortex-a76"]
|
||||
|
||||
[env]
|
||||
# The C/C++ compiler is pinned to clang because build.rs compiles the
|
||||
# parallel-rdp / retroachievements C sources with clang-only flags
|
||||
# (`-flto=thin`, cf. build.rs lines ~150-153). The `cc`/`cc-rs` crate
|
||||
# resolves clang via PATH, so hosts without it fail loudly at the C build
|
||||
# (issue #16: the review box runs the clang-18 shipped in the user-local
|
||||
# LLVM root — see scripts/gate.sh). AR is intentionally NOT pinned: the
|
||||
# platform `ar` (GNU binutils) archives clang objects fine, and llvm-ar is
|
||||
# not present in the provisioned root.
|
||||
SDKROOT = "/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk"
|
||||
CC = "clang"
|
||||
CXX = "clang++"
|
||||
AR = "llvm-ar"
|
||||
SDKROOT = "/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk"
|
||||
CMAKE_POLICY_VERSION_MINIMUM = "3.5" # for freetype
|
||||
|
||||
122
docs/build-gate.md
Normal file
122
docs/build-gate.md
Normal file
@ -0,0 +1,122 @@
|
||||
# Build gate (review box)
|
||||
|
||||
The project's review gate is a single documented command — see
|
||||
[scripts/gate.sh](../scripts/gate.sh):
|
||||
|
||||
```sh
|
||||
./scripts/gate.sh # == git submodule update --init --recursive
|
||||
# + cargo check --all-targets (type-check)
|
||||
# + cargo test --no-run (link tests)
|
||||
# + cargo test --lib (run headless lib tests)
|
||||
```
|
||||
|
||||
It must exit 0 (`GATE_OK`) on a clean `origin/main` checkout before any PR
|
||||
is gated (issue #16: all open PRs were unverifiable because `main` itself
|
||||
did not build; review bounce: the gate previously also stopped at
|
||||
`cargo check` — compiled but never linked or ran tests).
|
||||
|
||||
## Why the defaults were changed (`.cargo/config.toml`)
|
||||
|
||||
The fork's original config had two problems on older / non-LLVM hosts:
|
||||
|
||||
1. `-C target-cpu=x86-64-v3` for `x86_64` — requires AVX2/BMI2 (Intel
|
||||
Haswell, 2013+). On a pre-AVX2 host (the review box is Sandy Bridge,
|
||||
`x86-64-v2`) cargo applies the target rustflags to **build scripts**,
|
||||
which then miscompile: `num-traits`'s build script aborted with
|
||||
`memory allocation of 648518346341351440 bytes failed` (0x0900000000000010
|
||||
— garbage from executing AVX2 instructions, not real OOM).
|
||||
The default build is now portable; the optimised target is opt-in:
|
||||
`RUSTFLAGS="-C target-cpu=x86-64-v3" cargo build --release`
|
||||
(RUSTFLAGS replaces config rustflags — carry other flags across).
|
||||
2. `[env] AR=llvm-ar` forced an LLVM archiver that is not installed in the
|
||||
provisioned root — dropped; the platform `ar` (GNU binutils) archives
|
||||
clang objects fine. `CC=clang`/`CXX=clang++` are **retained** because
|
||||
`build.rs` compiles the parallel-rdp / retroachievements C sources with
|
||||
clang-only flags (`-flto=thin`); `cc-rs` resolves `clang` via PATH, so a
|
||||
host simply needs clang on PATH (the review box gets it from the
|
||||
user-local LLVM root via `gate.sh`).
|
||||
`CMAKE_POLICY_VERSION_MINIMUM=3.5` is retained (cmake >= 4 needs it for
|
||||
freetype); `SDKROOT` is retained for macOS SDK discovery.
|
||||
|
||||
## Host prerequisites (Linux)
|
||||
|
||||
- `cargo`/`rustc` (toolchain pinned in `rust-toolchain.toml`)
|
||||
- `clang`/`clang++` on PATH (build.rs, see above)
|
||||
- `cmake` (SDL3, freetype), `ar`, a real `pkg-config`
|
||||
- `fontconfig` dev (the GUI text stack pulls `yeslogic-fontconfig-sys`
|
||||
through `slint` → `parley` → `fontique`) and X11 dev (SDL3's video
|
||||
backend; the fork's own `src/ui.rs` uses `sdl3_sys::video` directly)
|
||||
- `libclang` (`LIBCLANG_PATH`) for the `bindgen` build-dependency's
|
||||
`clang-sys` probe
|
||||
|
||||
The review box has **no system packages for any of these and no sudo**, so
|
||||
user-local roots extracted from Ubuntu `.debs` are provisioned:
|
||||
|
||||
- `~/local-tools/root/usr/lib/llvm-18/bin` — clang/clang++/clang-18
|
||||
(plus `cmake`, `ninja`, `pkgconf`, `wayland-scanner` in
|
||||
`~/local-tools/root/usr/bin`), `libclang-18.so` in
|
||||
`~/local-tools/root/usr/lib/llvm-18/lib`
|
||||
- `~/local-tools/root/usr/lib/x86_64-linux-gnu` — the shared-lib root of
|
||||
the SAME provisioned tree as the `cmake`/`ninja` above. Those binaries
|
||||
link against `librhash.so.0`, `libuv.so.1`, `libjsoncpp.so.25` from this
|
||||
directory; without it on `LD_LIBRARY_PATH` cmake dies at exec time with
|
||||
`error while loading shared libraries: librhash.so.0` (exit 127) and
|
||||
`cmake-rs` misreports it as `is "cmake" not installed?`. `gate.sh` adds
|
||||
this root (see the `LLVM_BIN2` block), exactly like the other two roots.
|
||||
- `~/.local/bin-fc/pkg-config` — wrapper that execs the real `pkgconf`
|
||||
(the pypi `pkg-config`/`pkgconf-pypi` shims on `~/.local/bin` wrongly
|
||||
report exit 0 for missing packages, which makes cmake enable optional
|
||||
SDL backends)
|
||||
- `~/.local/fcroot/usr/lib/x86_64-linux-gnu/pkgconfig` — `fontconfig.pc`,
|
||||
`freetype2.pc`, `zlib.pc`, `expat.pc`, `libpng16.pc`, X11 pc files, with
|
||||
matching headers and shared libs in the same root
|
||||
|
||||
`scripts/gate.sh` wires all of these onto PATH/env when present; on hosts
|
||||
with system toolchains the provisioning blocks are no-ops.
|
||||
|
||||
## What the gate runs, and why
|
||||
|
||||
Three steps, so a failure is attributable to exactly one phase:
|
||||
|
||||
1. `cargo check --all-targets` — type-checks every target including tests.
|
||||
This is the historical blocker phase (#16: `num-traits` SIGABRT under
|
||||
the old `target-cpu=x86-64-v3`).
|
||||
2. `cargo test --no-run` — LINKS every test binary. A test that
|
||||
type-checks but cannot link is still a broken gate; `cargo check` alone
|
||||
never proves linkability. This answers the review question "the gate
|
||||
compiles the tests but never runs them" for the link half.
|
||||
3. `cargo test --lib` — EXECUTES the library unit tests (headless: the
|
||||
netplay state-sync/rollback logic; no window or device needed). Test
|
||||
execution was deliberately NOT assumed: this step is wired in because it
|
||||
completes on the review box. `main` currently has 0 `#[test]` fns
|
||||
(measured in the #16 review; the inbound netplay PRs add ~38), so a
|
||||
clean run reports `0 passed` — the mechanism, not the coverage, is what
|
||||
this gate guarantees until those PRs land.
|
||||
|
||||
Decision record: `cargo test --no-run` and `cargo test --lib` were both
|
||||
verified to complete here; running the full `cargo test` (which would also
|
||||
run windowed/bin tests) was not wired because it needs an interactive
|
||||
display and the review box's gate must stay headless-deterministic.
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
- `memory allocation of 648518346341351440 bytes failed` (SIGABRT in a
|
||||
dependency build script) — an x86-64-v3 (or other AVX2-only) flag is
|
||||
being applied on a pre-AVX2 CPU. Remove the flag / use the portable
|
||||
default.
|
||||
- `cc1: error: unrecognized argument to '-flto=' option: 'thin'` —
|
||||
`build.rs` requires clang; gcc rejects `-flto=thin`. Put clang on PATH
|
||||
(or run via `scripts/gate.sh` on the review box).
|
||||
- `failed to find tool "clang"` inside `ring`'s build — clang is missing
|
||||
from PATH.
|
||||
- `Package 'fontconfig' not found` — PKG_CONFIG_PATH is not pointing at a
|
||||
fontconfig dev root (or the pypi pkg-config shim is intercepting).
|
||||
- SDL cmake: `SDL could not find X11 or Wayland development libraries` —
|
||||
CMake's FindX11 needs `CMAKE_INCLUDE_PATH`/`CMAKE_LIBRARY_PATH` pointed
|
||||
at the X11 dev root (pkg-config alone is not consulted for X11).
|
||||
- `cmake: error while loading shared libraries: librhash.so.0` (exit 127),
|
||||
reported by cmake-rs as `is "cmake" not installed?` — the provisioned
|
||||
cmake/ninja need their OWN root
|
||||
(`~/local-tools/root/usr/lib/x86_64-linux-gnu`) on `LD_LIBRARY_PATH`;
|
||||
`gate.sh`'s `LLVM_BIN2` block does this. This was the issue #16 review
|
||||
bounce.
|
||||
81
scripts/gate.sh
Executable file
81
scripts/gate.sh
Executable file
@ -0,0 +1,81 @@
|
||||
#!/usr/bin/env bash
|
||||
# gopher64-netplay review gate (issue #16)
|
||||
#
|
||||
# Documented gate command (from a clean origin/main checkout):
|
||||
# ./scripts/gate.sh
|
||||
#
|
||||
# What it does:
|
||||
# 1. `git submodule update --init --recursive` (parallel-rdp,
|
||||
# retroachievements/rcheevos, src/compat/sse2neon) — required by
|
||||
# build.rs.
|
||||
# 2. Wires the review box's user-local provisioning onto PATH/env (only
|
||||
# when present; a no-op on hosts with system toolchains):
|
||||
# - clang/clang++ from the local LLVM-18 root (build.rs requires
|
||||
# clang for `-flto=thin`)
|
||||
# - a real pkgconf + fontconfig/X11 dev pc files (the box has no
|
||||
# system pkg-config/fontconfig and no sudo)
|
||||
# - the provisioned cmake/ninja's OWN lib root on LD_LIBRARY_PATH
|
||||
# (without it cmake dies with exit 127: librhash/libuv/libjsoncpp
|
||||
# not found)
|
||||
# 3. Runs the gate, as three distinguishable steps:
|
||||
# a. `cargo check --all-targets` — TYPE-check everything, tests
|
||||
# included (compile-only; the historical main blocker)
|
||||
# b. `cargo test --no-run` — LINK every test binary (a test
|
||||
# that type-checks but cannot link is still a broken gate)
|
||||
# c. `cargo test --lib` — EXECUTE the headless library unit
|
||||
# tests (netplay state sync etc.; see docs/build-gate.md)
|
||||
#
|
||||
# On AVX2-capable hardware, opt into the optimised CPU target:
|
||||
# RUSTFLAGS="-C target-cpu=x86-64-v3" ./scripts/gate.sh
|
||||
# (RUSTFLAGS REPLACES the config's rustflags for the whole invocation, so
|
||||
# carry any other flags you need.)
|
||||
set -euo pipefail
|
||||
REPO_ROOT="$(cd "$(dirname "$0")/.." && pwd)"
|
||||
cd "$REPO_ROOT"
|
||||
|
||||
git submodule update --init --recursive
|
||||
|
||||
# --- Review-box provisioning ----------------------------------------------
|
||||
LLVM_BIN="$HOME/local-tools/root/usr/lib/llvm-18/bin"
|
||||
LLVM_BIN2="$HOME/local-tools/root/usr/bin"
|
||||
FCPC="$HOME/.local/bin-fc/pkg-config"
|
||||
FCROOT="$HOME/.local/fcroot/usr"
|
||||
PC_DIR="$FCROOT/lib/x86_64-linux-gnu/pkgconfig"
|
||||
|
||||
if [ -d "$LLVM_BIN" ]; then
|
||||
export PATH="$LLVM_BIN:$PATH" # clang / clang++ (build.rs needs clang)
|
||||
fi
|
||||
if [ -d "$LLVM_BIN2" ]; then
|
||||
export PATH="$LLVM_BIN2:$PATH" # cmake, ninja, pkgconf, wayland-scanner
|
||||
# cmake/ninja from this root link against librhash/libuv/libjsoncpp that
|
||||
# ship in the SAME root (`usr/lib/x86_64-linux-gnu`); without that dir on
|
||||
# LD_LIBRARY_PATH they die with exit 127 and cmake-rs reports it as
|
||||
# "is `cmake` not installed?" — the issue #16 review bounce.
|
||||
export LD_LIBRARY_PATH="$HOME/local-tools/root/usr/lib/x86_64-linux-gnu${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}"
|
||||
fi
|
||||
if [ -x "$FCPC" ] && [ -d "$PC_DIR" ]; then
|
||||
export PATH="$(dirname "$FCPC"):$PATH" # real pkg-config (not the pypi shim)
|
||||
export PKG_CONFIG_PATH="$PC_DIR"
|
||||
# SDL's cmake resolves X11 via CMake's classic FindX11 module (path
|
||||
# scan), not through pkg-config — point those scans at the root too.
|
||||
export CMAKE_INCLUDE_PATH="$FCROOT/include${CMAKE_INCLUDE_PATH:+:$CMAKE_INCLUDE_PATH}"
|
||||
export CMAKE_LIBRARY_PATH="$FCROOT/lib/x86_64-linux-gnu${CMAKE_LIBRARY_PATH:+:$CMAKE_LIBRARY_PATH}"
|
||||
export LD_LIBRARY_PATH="$FCROOT/lib/x86_64-linux-gnu${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}"
|
||||
fi
|
||||
if [ -d "$HOME/local-tools/root/usr/lib/llvm-18/lib" ]; then
|
||||
export LIBCLANG_PATH="$HOME/local-tools/root/usr/lib/llvm-18/lib" # bindgen/clang-sys
|
||||
export LD_LIBRARY_PATH="$HOME/local-tools/root/usr/lib/llvm-18/lib${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}"
|
||||
fi
|
||||
|
||||
# --- Gate: type-check, then link tests, then run the headless lib tests ----
|
||||
echo "GATE step 1/3: cargo check --all-targets"
|
||||
cargo check --all-targets
|
||||
|
||||
echo "GATE step 2/3: cargo test --no-run"
|
||||
cargo test --no-run
|
||||
|
||||
echo "GATE step 3/3: cargo test --lib"
|
||||
cargo test --lib
|
||||
|
||||
echo "GATE_OK"
|
||||
|
||||
Reference in New Issue
Block a user