| 1 | #!/usr/bin/env bash |
| 2 | # Build the core crate for wazero. No wasm-bindgen, no wasm-pack: the Go host |
| 3 | # provides no JS glue, so the module must be plain wasm32 with a C ABI. |
| 4 | set -euo pipefail |
| 5 | cd "$(dirname "$0")/.." |
| 6 | # Lint before building: disallowed-methods (clippy.toml) enforces the |
| 7 | # Doc-construction rule documented in core/src/lib.rs — Doc::new() and |
| 8 | # Doc::with_client_id() both draw entropy this build has no safe source |
| 9 | # for. A doc comment alone has been wrong, or gotten around, more than |
| 10 | # once; this is the actual enforcement. |
| 11 | if [[ "${1:-}" != "--build-only" && "${1:-}" != "--canonical-build" ]]; then |
| 12 | cargo clippy --manifest-path core/Cargo.toml --all-targets -- -D warnings -D clippy::disallowed_methods |
| 13 | fi |
| 14 | # Rust/Cargo crate identities affect code ordering even after path remapping. |
| 15 | # Build on Linux amd64 at fixed source/toolchain paths on every host. |
| 16 | if [[ "${1:-}" == "--canonical-build" ]]; then |
| 17 | [[ "$(uname -s)/$(uname -m)" == "Linux/x86_64" && "$(pwd)" == /work \ |
| 18 | && "$CARGO_HOME" == /usr/local/cargo && "$RUSTUP_HOME" == /usr/local/rustup ]] \ |
| 19 | || { echo "build-wasm: invalid canonical build environment" >&2; exit 1; } |
| 20 | export CARGO_TARGET_DIR=/work/core/target RUSTUP_TOOLCHAIN=1.98.0 |
| 21 | else |
| 22 | out="core/target/wasm32-unknown-unknown/release/docs_core.wasm" |
| 23 | mkdir -p "$(dirname "$out")" |
| 24 | temporary=$(mktemp "${out}.XXXXXX") |
| 25 | trap 'rm -f "$temporary"' EXIT |
| 26 | if [[ "$(uname -s)/$(uname -m)" == "Linux/x86_64" ]] && command -v bwrap >/dev/null; then |
| 27 | cargo_home=$(cd "${CARGO_HOME:-$HOME/.cargo}" && pwd) |
| 28 | rustup_home=$(cd "${RUSTUP_HOME:-$HOME/.rustup}" && pwd) |
| 29 | mkdir -p core/target/canonical-linux-amd64 |
| 30 | bwrap --tmpfs / \ |
| 31 | --ro-bind /usr /usr --tmpfs /usr/local \ |
| 32 | --ro-bind /bin /bin --ro-bind /lib /lib --ro-bind /lib64 /lib64 \ |
| 33 | --ro-bind /etc /etc --bind /tmp /tmp --proc /proc --dev /dev \ |
| 34 | --ro-bind "$(pwd)" /work \ |
| 35 | --bind "$(pwd)/core/target/canonical-linux-amd64" /work/core/target \ |
| 36 | --bind "$cargo_home" /usr/local/cargo --ro-bind "$rustup_home" /usr/local/rustup \ |
| 37 | --chdir /work --setenv CARGO_HOME /usr/local/cargo --setenv RUSTUP_HOME /usr/local/rustup \ |
| 38 | --setenv PATH /usr/local/cargo/bin:/usr/local/bin:/usr/bin:/bin \ |
| 39 | bash -ec './scripts/build-wasm.sh --canonical-build >&2; cat core/target/wasm32-unknown-unknown/release/docs_core.wasm' > "$temporary" |
| 40 | else |
| 41 | command -v docker >/dev/null || { echo "build-wasm: install Docker, or bubblewrap on Linux amd64" >&2; exit 1; } |
| 42 | target_key=$(printf %s "$(pwd)" | shasum -a 256 | cut -c1-16) |
| 43 | docker run --rm --platform linux/amd64 \ |
| 44 | --mount "type=bind,source=$(pwd),target=/work,readonly" \ |
| 45 | --mount "type=volume,source=oficina-docs-wasm-target-${target_key},target=/work/core/target" \ |
| 46 | --mount type=volume,source=oficina-docs-wasm-cargo,target=/usr/local/cargo \ |
| 47 | --mount type=volume,source=oficina-docs-wasm-rustup,target=/usr/local/rustup \ |
| 48 | --workdir /work \ |
| 49 | rust@sha256:8aea3a845c48caac4091a8d0e6494d213061f8f014dc2f5a5f1a88a1a8c9f301 \ |
| 50 | bash -ec 'rustup target add wasm32-unknown-unknown >&2; ./scripts/build-wasm.sh --canonical-build >&2; cat core/target/wasm32-unknown-unknown/release/docs_core.wasm' > "$temporary" |
| 51 | fi |
| 52 | mv "$temporary" "$out" |
| 53 | exit 0 |
| 54 | fi |
| 55 | # --lib only: the wasm module shipped to wazero is the library crate. Native |
| 56 | # tooling under src/bin (e.g. emit_update, used from the host side of |
| 57 | # wire-gate.sh) is never part of that artifact and does not define the |
| 58 | # __getrandom_v03_custom symbol itself, so building it for wasm32 fails to |
| 59 | # link -- it was never meant to run there. |
| 60 | # |
| 61 | # --remap-path-prefix (x2): rustc embeds the absolute source path of every |
| 62 | # panic site (Location::caller()) into the binary. Left alone, that means |
| 63 | # the registry path of every dependency (which contains $HOME, so it |
| 64 | # leaks a username) and this worktree's own absolute path end up baked |
| 65 | # into docs_core.wasm -- so the artifact only reproduces byte-for-byte on |
| 66 | # the machine, and under the $HOME, that built it. The gate's `cmp` |
| 67 | # against the committed copy then fails everywhere else and misreports |
| 68 | # a stale artifact instead of a non-reproducible build. Remapping both |
| 69 | # roots to fixed placeholders makes the build's output independent of |
| 70 | # where it ran. |
| 71 | # |
| 72 | # Setting RUSTFLAGS here does not merge with .cargo/config.toml's |
| 73 | # target.wasm32-unknown-unknown.rustflags -- an env RUSTFLAGS replaces a |
| 74 | # config-file rustflags for the same target outright, it does not append |
| 75 | # to it. That config entry (--cfg getrandom_backend="custom") is what |
| 76 | # routes getrandom to our no-JS-import backend on wasm32; dropping it |
| 77 | # breaks the build (getrandom falls back to a backend wasm32-unknown- |
| 78 | # unknown doesn't support) rather than just losing the cfg silently. So |
| 79 | # it has to be repeated here alongside the remap flags. |
| 80 | registry_root="${CARGO_HOME:-$HOME/.cargo}/registry/src" |
| 81 | workspace_root="$(pwd)" |
| 82 | # Cargo also puts local path dependency identities into mangled debug names. |
| 83 | # Remove that optional symbol section so identical code reproduces across worktrees. |
| 84 | export RUSTFLAGS="-C strip=symbols --cfg getrandom_backend=\"custom\" --remap-path-prefix=${registry_root}=/cargo-registry-src --remap-path-prefix=${workspace_root}=/docs-core" |
| 85 | cargo build --release --manifest-path core/Cargo.toml --target wasm32-unknown-unknown --locked --lib |
| 86 | out="core/target/wasm32-unknown-unknown/release/docs_core.wasm" |
| 87 | [ -f "$out" ] || { echo "build-wasm: no artifact at $out" >&2; exit 1; } |
| 88 | echo "$out ($(wc -c < "$out") bytes)" |
| 89 | |