UNPKG

@wasm-tool/rollup-plugin-rust

Version:

Rollup plugin for bundling and importing Rust crates.

206 lines (153 loc) 5.7 kB
import { getEnv, exec, debug, spawn, Lock } from "./utils.js"; const GLOBAL_LOCK = new Lock(); export class Nightly { constructor(year, month, day) { this.year = year; this.month = month; this.day = day; } greaterThan(other) { if (this.year > other.year) { return true; } else if (this.year === other.year) { if (this.month > other.month) { return true; } else if (this.month === other.month) { return this.day > other.day; } else { return false; } } else { return false; } } supportsImmediateAbort() { return this.greaterThan(new Nightly(2025, 10, 4)); } } export async function getNightly(dir) { const bin = getEnv("CARGO_BIN", "cargo"); // TODO make this faster somehow ? const version = await exec(`${bin} --version`, { cwd: dir }); const a = /\-nightly \([^ ]+ ([0-9]+)\-([0-9]+)\-([0-9]+)\)/.exec(version); if (a) { return new Nightly(+a[1], +a[2], +a[3]); } else { return null; } } export async function getTargetDir(dir) { const bin = getEnv("CARGO_BIN", "cargo"); // TODO make this faster somehow ? const metadata = await exec(`${bin} metadata --format-version 1 --no-deps --color never`, { cwd: dir }); return JSON.parse(metadata)["target_directory"]; } export async function getVersion(dir, name) { const bin = getEnv("CARGO_BIN", "cargo"); const spec = await exec(`${bin} pkgid ${name}`, { cwd: dir }); const version = /([\d\.]+)[\r\n]*$/.exec(spec); if (version) { return version[1]; } else { throw new Error(`Could not determine ${name} version`); } } export async function run({ dir, verbose, cargoArgs, rustcArgs, release, optimize, nightly, atomics, strip }) { const cargoBin = getEnv("CARGO_BIN", "cargo"); let args = [ "rustc", "--lib", "--target", "wasm32-unknown-unknown", "--crate-type", "cdylib", // Needed for wasm-bindgen to work ]; let rustflags = []; if (atomics) { rustflags.push( "-C", "target-feature=+atomics,+bulk-memory,+mutable-globals", // https://github.com/rust-lang/rust/pull/156174 "-C", "link-arg=--max-memory=1073741824", "-C", "link-arg=--shared-memory", "-C", "link-arg=--import-memory", "-C", "link-arg=--export=__heap_base", "-C", "link-arg=--export=__wasm_init_tls", "-C", "link-arg=--export=__tls_size", "-C", "link-arg=--export=__tls_align", "-C", "link-arg=--export=__tls_base", ); args.push("-Z", "build-std=panic_abort,core,std,alloc,proc_macro"); } // https://doc.rust-lang.org/cargo/reference/profiles.html#release if (release) { args.push("--release"); if (nightly) { if (strip.location.get()) { rustflags.push("-Z", "location-detail=none"); } if (strip.formatDebug.get()) { rustflags.push("-Z", "fmt-debug=none"); } } if (optimize) { // Wasm doesn't support unwind, so we abort instead if (nightly && nightly.supportsImmediateAbort()) { // Reduces file size by removing panic strings args.push("--config"); args.push("profile.release.panic=\"immediate-abort\""); } else { args.push("--config"); args.push("profile.release.panic=\"abort\""); } // Improves runtime performance and file size args.push("--config"); args.push("profile.release.lto=true"); // Improves runtime performance args.push("--config"); args.push("profile.release.codegen-units=1"); // Reduces file size args.push("--config"); args.push("profile.release.strip=true"); // Reduces file size by removing panic strings if (nightly) { if (nightly.supportsImmediateAbort()) { args.push("-Z", "panic-immediate-abort"); } args.push("-Z", "build-std=panic_abort,core,std,alloc,proc_macro"); args.push("-Z", "build-std-features=optimize_for_size"); } } // https://doc.rust-lang.org/cargo/reference/profiles.html#dev } else { if (optimize) { // Wasm doesn't support unwind args.push("--config"); args.push("profile.dev.panic=\"abort\""); args.push("--config"); args.push("profile.dev.lto=\"off\""); // Speeds up compilation // https://github.com/MoonZoon/MoonZoon/issues/170 args.push("--config"); args.push("profile.dev.debug=false"); } } rustflags = rustflags.concat(rustcArgs); if (rustflags.length > 0) { args.push("--config", "build.rustflags=" + JSON.stringify(rustflags)); } args = args.concat(cargoArgs); await GLOBAL_LOCK.withLock(async () => { if (verbose) { debug(`Running cargo ${args.join(" ")}`); } try { await spawn(cargoBin, args, { cwd: dir, stdio: "inherit" }); } catch (e) { if (verbose) { throw e; } else { const e = new Error("Rust compilation failed"); e.stack = null; throw e; } } }); }