Last active
November 5, 2024 22:20
-
-
Save Lohann/b3399bc52cde9aebe2fb76df1dfe59f5 to your computer and use it in GitHub Desktop.
WebAssembly Base Project
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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"); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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