Skip to content

Instantly share code, notes, and snippets.

@Lohann
Last active November 5, 2024 22:20
Show Gist options
  • Save Lohann/b3399bc52cde9aebe2fb76df1dfe59f5 to your computer and use it in GitHub Desktop.
Save Lohann/b3399bc52cde9aebe2fb76df1dfe59f5 to your computer and use it in GitHub Desktop.
WebAssembly Base Project
fn main() {
if matches!(std::env::var("CARGO_CFG_TARGET_FAMILY").ok().as_deref(), Some("wasm")) {
std::env::set_var("CARGO_ENCODED_RUSTFLAGS", "-Clink-arg=-zstack-size=65536\x1f-Clink-arg=--import-memory\x1f-Ctarget-cpu=mvp");
}
}
#!/bin/bash
set -e
####################################################################
# STEP 1: Build the project with the wasm32-unknown-unknown target #
####################################################################
# Set the stack size to 64KB
STACK_SIZE=65536
# List of custom flags to pass to all compiler invocations that Cargo performs.
RUST_WASM_FLAGS=(
# Max wasm stack size
"-Clink-arg=-zstack-size=$STACK_SIZE"
# Configure the wasm target to import instead of export memory
'-Clink-arg=--import-memory'
# Doesn't optimize this build for any specific CPU
'-Ctarget-cpu=mvp'
)
# Separated flags by 0x1f (ASCII Unit Separator)
# Reference: https://doc.rust-lang.org/cargo/reference/environment-variables.html#environment-variables-cargo-reads
RUST_WASM_FLAGS="$(printf '%s\x1f%s\x1f%s' ${RUST_WASM_FLAGS[@]})"
echo "$RUST_WASM_FLAGS"
# Build the project with the wasm32-unknown-unknown target
CARGO_ENCODED_RUSTFLAGS="$RUST_WASM_FLAGS" cargo build --release --target=wasm32-unknown-unknown
######################################################
# Remove unnecessary code and optimize the wasm file #
######################################################
# Run `wasm-opt --help` to see all available options
WASM_OPT_OPTIONS=(
-O3
--dce
--precompute
--precompute-propagate
--optimize-instructions
--optimize-casts
--low-memory-unused
--optimize-added-constants
--optimize-added-constants-propagate
--simplify-globals-optimizing
--inlining-optimizing
--once-reduction
--merge-locals
--merge-similar-functions
--strip
--strip-debug
# --remove-memory
--remove-unused-names
--remove-unused-types
--remove-unused-module-elements
--duplicate-function-elimination
--duplicate-import-elimination
--reorder-functions
--abstract-type-refining
--alignment-lowering
--avoid-reinterprets
# --zero-filled-memory
--disable-simd
--disable-threads
--disable-gc
--disable-multivalue
--disable-reference-types
--disable-exception-handling
--optimize-stack-ir
--vacuum
--unsubtyping
)
# Create the `optimized.wasm` file (binary format)
wasm-opt \
"${WASM_OPT_OPTIONS[@]}" \
--output ./optimized.wasm \
./target/wasm32-unknown-unknown/release/rust_wasm_minimal.wasm
# Create the `optimized.wat` file (text format)
wasm-opt \
"${WASM_OPT_OPTIONS[@]}" \
--emit-text \
--output ./optimized.wat \
./target/wasm32-unknown-unknown/release/rust_wasm_minimal.wasm
# Print the `optimized.wat` file
cat ./optimized.wat
[package]
name = "rust-wasm-minimal"
version = "0.1.0"
edition = "2021"
[lib]
name = "rust_wasm_minimal"
crate-type = ["cdylib"]
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
rand = { version = "0.8.4" }
[profile.release]
opt-level = 3
lto = "fat"
codegen-units = 1
panic = "abort"
strip = "symbols"
debug = false
overflow-checks = false
debug-assertions = false
incremental = false
// Disable `std` library and `main` entrypoint, because it's not available in WebAssembly.
// OBS: `std` and `main` are only available when running tests.
#![cfg_attr(all(target_arch = "wasm32", not(test)), no_std, no_main)]
// Override the default panic handler when compilling to WebAssembly.
// Reference: https://doc.rust-lang.org/nomicon/panic-handler.html
#[cfg(target_arch = "wasm32")]
#[panic_handler]
unsafe fn panic(_info: &core::panic::PanicInfo) -> ! {
core::arch::wasm32::unreachable()
}
/// Adds two numbers.
#[no_mangle]
pub const extern "C" fn add(a: u32, b: u32) -> u32 {
a + b
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn it_works() {
let result = add(2, 2);
assert_eq!(result, 4);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment