From c01413544660088f708cc25a38aa7ed5ecb0267f Mon Sep 17 00:00:00 2001 From: Tim Disney Date: Thu, 06 Aug 2026 19:14:04 +0000 Subject: [PATCH] update wasm build for private spaces --- .tangled/workflows/deploy.yml | 33 +++++++++++++++++++++++++++++++++ packages/transport-iroh-wasm/rust/Cargo.toml | 18 ++++++++++++++++++ 2 file(s) changed, 51 insertion(s)(+), 0 deletion(s)(-) diff --git a/.tangled/workflows/deploy.yml b/.tangled/workflows/deploy.yml --- a/.tangled/workflows/deploy.yml +++ b/.tangled/workflows/deploy.yml @@ -60,7 +60,40 @@ command: | set -euo pipefail rustup toolchain install stable --profile minimal --target wasm32-unknown-unknown + export PATH="$HOME/.cargo/bin:$PATH" + + # wasm-pack shells out to `wasm-bindgen`, and when it cannot find a version-matching one on + # PATH it downloads a prebuilt glibc binary from GitHub — which does not exec on nixos, where + # there is no `/lib64/ld-linux`. So supply it ourselves. The version is READ FROM Cargo.lock + # rather than written here, because wasm-pack refuses a CLI that disagrees with the crate's + # `wasm-bindgen` and a literal pinned in a workflow file would drift silently on the next + # `cargo update`. This costs a few minutes of build per deploy; that is the price of not + # depending on nixpkgs happening to carry the exact patch release. + lock=packages/transport-iroh-wasm/rust/Cargo.lock + wb_version="$(awk '/^name = "wasm-bindgen"$/ { getline; gsub(/[",]/, ""); print $3; exit }' "$lock")" + : "${wb_version:?no wasm-bindgen version in $lock}" + echo "wasm-bindgen : $wb_version (from $lock)" + cargo install wasm-bindgen-cli --version "$wb_version" --locked + export AR_wasm32_unknown_unknown="$(command -v llvm-ar)" + # Everything below is ci.yml's "Browser transport crate" step verbatim, and has to stay that + # way: `wasm-pack build` compiles the same `ring` C that `cargo check` does, so it meets the + # same nixpkgs cc-wrapper. That wrapper is built for the HOST triple and says itself it "is + # currently not designed with multi-target compilation in mind"; it injects x86-only hardening + # (`-fzero-call-used-regs=used-gpr`) and the host glibc's include directory, which defeats + # ring's own `-nostdlibinc` — clang's `stdint.h` `#include_next`s straight into glibc and dies + # on a missing `gnu/stubs-32.h`. Drop the hardening and hand the C compile to the unwrapped + # clang the wrapper itself points at. + export NIX_HARDENING_ENABLE="" + wrapper_root="$(dirname "$(dirname "$(readlink -f "$(command -v clang)")")")" + unwrapped="$(cat "$wrapper_root/nix-support/orig-cc" 2>/dev/null || true)" + echo "clang wrapper : $wrapper_root" + echo "unwrapped cc : ${unwrapped:-}" + if [ -x "${unwrapped:-/nonexistent}/bin/clang" ]; then + export CC_wasm32_unknown_unknown="$unwrapped/bin/clang" + else + echo "no orig-cc; nix-support holds:"; ls "$wrapper_root/nix-support" || true + fi pnpm --filter @radial/transport-iroh-wasm build:wasm - name: "Build" diff --git a/packages/transport-iroh-wasm/rust/Cargo.toml b/packages/transport-iroh-wasm/rust/Cargo.toml --- a/packages/transport-iroh-wasm/rust/Cargo.toml +++ b/packages/transport-iroh-wasm/rust/Cargo.toml @@ -20,3 +20,21 @@ [profile.release] opt-level = "s" lto = true + +# wasm-pack's post-processing pass, off deliberately. Left on, wasm-pack downloads a prebuilt +# binaryen from GitHub — a glibc binary that does not exec on the nixos image the deploy builds on +# (`.tangled/workflows/deploy.yml`). +# +# What that costs, measured rather than guessed (2026-08-06, `wasm-opt -Os` vs none): +# +# raw 2,123,989 → 3,054,628 bytes (+44%) +# brotli 716,646 → 772,958 bytes (+7.9%) +# +# The transfer number is the one a person waits on — Cloudflare Pages serves this brotli-compressed, +# so the pass is worth ~56 kB on the wire. The raw number is real too, since it is what the browser +# decodes and compiles, but it is paid once per tab and only by tabs that open a private space (the +# binding is dynamically imported). Against that: a downloaded, unpinned optimizer in the deploy +# path, and a build product that differs between a developer's machine and production. Off +# everywhere rather than conditional, so those two are always the same bytes. +[package.metadata.wasm-pack.profile.release] +wasm-opt = false -- tangled.sh