From f1515265a29704dbecc183efb7ed9dcd3057fa41 Mon Sep 17 00:00:00 2001 From: Christopher Serr Date: Tue, 8 Nov 2022 01:18:32 +0100 Subject: [PATCH] Build Rust's `std` with immediate abort (#746) We generally want the wasm file to be as compact as possible. However because there's so many paths in Rust code that could panic, but don't ever in practice as they are meant to signal bugs, the wasm file has to keep around all those panic paths, and even worse, all the code for formatting the panic messages for all those different types that could be involved in a panic. This bloats the binary a lot. There's a nightly feature to build the standard library as part of your compilation and with that you can pass various features to the standard library, just like with any other crate. And one of those features is to remove all the formatting machinery from the panics and just immediately abort, resulting in smaller binaries. On top of that by building the standard library ourselves we also get to build it with all our target features, meaning that its code will make use of all the additional WebAssembly instructions that have been added since the MVP. So this essentially is a big win. However this forces us to use the nightly compiler, but it usually is actually quite stable. We won't be using any nightly features of the language itself and only optionally use the compiler in our CI, so the stable compiler continues to work just fine for local development. --- .github/workflows/ci.yml | 5 ++++- buildCore.js | 9 +++++++-- package.json | 1 + 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c258999..94318c4 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -45,6 +45,9 @@ jobs: - name: Install Rust uses: hecrj/setup-rust-action@v1 + with: + rust-version: nightly + components: rust-src - name: Install target run: rustup target add wasm32-unknown-unknown @@ -75,7 +78,7 @@ jobs: - name: Build Core run: | set -e - npm run build:core:production + npm run build:core:deploy - name: Set up tslint matcher run: echo "::add-matcher::.github/workflows/tslint.json" diff --git a/buildCore.js b/buildCore.js index 7d583fd..35ffebd 100644 --- a/buildCore.js +++ b/buildCore.js @@ -2,14 +2,19 @@ import { execSync } from "child_process"; import fs from "fs"; let buildFlags = ""; +let toolchain = ""; let targetFolder = "debug"; if (process.argv.some((v) => v === "--production")) { buildFlags = "--release"; targetFolder = "release"; } +if (process.argv.some((v) => v === "--nightly")) { + toolchain = "+nightly"; + buildFlags += " -Z build-std=std,panic_abort -Z build-std-features=panic_immediate_abort"; +} execSync( - "cargo run", + `cargo ${toolchain} run`, { cwd: "livesplit-core/capi/bind_gen", stdio: "inherit", @@ -17,7 +22,7 @@ execSync( ); execSync( - `cargo rustc -p livesplit-core-capi --crate-type cdylib --features wasm-web --target wasm32-unknown-unknown ${buildFlags}`, + `cargo ${toolchain} rustc -p livesplit-core-capi --crate-type cdylib --features wasm-web --target wasm32-unknown-unknown ${buildFlags}`, { cwd: "livesplit-core", stdio: "inherit", diff --git a/package.json b/package.json index dc37777..08335e5 100644 --- a/package.json +++ b/package.json @@ -8,6 +8,7 @@ "build": "webpack", "build:core": "node buildCore.js", "build:core:production": "node buildCore.js --production", + "build:core:deploy": "node buildCore.js --production --nightly", "lint": "tslint --project tsconfig.json", "publish": "webpack --mode production", "serve": "webpack serve",