diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 85c167d..97abdbd 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -131,14 +131,17 @@ jobs: - name: Build release binary env: - # Smaller, more portable binaries. LTO is on by default in - # the `release` profile; this just makes binaries strip-friendly. + # LTO and codegen units come from `[profile.release]` in + # Cargo.toml. Symbols are left in here and removed by the + # target's own `strip` in the next step. CARGO_PROFILE_RELEASE_STRIP: none + # `--bin hoverfly`: sigcheck isn't shipped, so don't pay for a + # second fat-LTO link. run: | if [ "${{ matrix.use-cross }}" = "true" ]; then - cross build --release --locked --target ${{ matrix.target }} + cross build --release --locked --target ${{ matrix.target }} --bin hoverfly else - cargo build --release --locked --target ${{ matrix.target }} + cargo build --release --locked --target ${{ matrix.target }} --bin hoverfly fi - name: Strip binary diff --git a/AGENTS.md b/AGENTS.md index a67d8a4..6b9fc8f 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -70,6 +70,11 @@ are in flight at once. Public API (`Behaviour`, `Control`, `IncomingStreams`, - Native: `cargo build` / `cargo build --release`. Release is ~2-5× faster on crypto paths but only ~10-15% end-to-end (network dominates). +- `[profile.release]` is tuned for binary size: fat LTO, `codegen-units = 1`. + A release build is a full slow rebuild; iterate on `cargo build`. Don't + switch it to `panic = "abort"` for the extra ~2 MiB: unwinding is what + confines a panic to the one tokio task (peer session, daemon request, + relay connection) it happened in. - Edition **2024**; crate version tracked in `Cargo.toml` (`0.x`, currently `0.3.0`). - Default features are `cli`, `bridge`, `pusher`. `--no-default-features diff --git a/Cargo.toml b/Cargo.toml index 60952ac..10ab81e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -189,3 +189,14 @@ tokio-test = "0.4" # from `proto/*.proto`. Not pulled into normal `cargo build` — invoke # explicitly via `scripts/regen-protos.sh`. prost-build = "0.13" + +# Binary size over build time. Without LTO each of the default 16 codegen +# units carries its own copy of every async body and closure it touches; +# fat LTO with a single unit merges them. cargo can't LTO the cdylib+rlib lib +# target, so the wasm build only gets the single unit. Panics stay `unwind` +# despite the unwind tables: each peer session drives its swarm in its own +# task, and a panic there (say, a dependency choking on a peer's bytes) must +# drop that session, not the whole upload, daemon or relay. +[profile.release] +lto = "fat" +codegen-units = 1