Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I generate a minimal wasm file with Rust?

I can generate a fairly minimal (203 bytes) wasm file from the following C code by running emcc -O3 -s WASM=1 -s SIDE_MODULE=1 -o sum.wasm sum.c.

#include <emscripten/emscripten.h>

int EMSCRIPTEN_KEEPALIVE sum(int a, int b) {
    return a + b;
}

Disassembled output:

(module
 (type $0 (func (param i32 i32) (result i32)))
 ... trim 9 lines ...
 (export "_sum" (func $0))
 (func $0 (type $0) (param $var$0 i32) (param $var$1 i32) (result i32)
  (i32.add
   (get_local $var$1)
   (get_local $var$0)
  )   
 )   
 ... trim 17 lines ...
)

But given the following Rust code

pub fn main() {}

#[no_mangle]
pub extern fn sum(a: i32, b: i32) -> i32 {
    a + b
}

I cannot seem to produce anything similar.

rustc -O --target=wasm32-unknown-emscripten sum.rs works but gives me an 85k wasm file and a 128k js file.

I've tried exporting EMMAKEN_CFLAGS='-s WASM=1 -s SIDE_MODULE=1' but that gives me a number of warnings like

Input file "/tmp/.../rust.metadata.bin" exists but was not an LLVM bitcode file suitable for Emscripten. Perhaps accidentally mixing native built object files with Emscripten?

and then fails to link.

My Rust version is 1.22.0-nightly (c6884b12d 2017-09-30) and my emcc version is 1.37.21.

What am I doing wrong?

like image 725
zakm Avatar asked Oct 10 '17 02:10

zakm


1 Answers

With the wasm32-unknown-emscripten target, you're using an Emscripten-based compiler toolchain. Emscripten adds quite a bit of additional runtime code into the wasm module, as well as additional JavaScript code for integrating with this at runtime. As you have also observed, Emscripten can compile with a SIDE_MODULE option that removes the vast majority of this runtime code. This reduces the wasm binary size, but means that you must handle things such as binding complex types yourself.

Very recently (Nov, 2017) a new wasm32-unknown-unknown target was added to Rust, which uses the LLVM backend (rather than Emscripten and its fastcomp fork), resulting in a minimal output.

This target can be used as described in the setup guide:

rustup update
rustup target add wasm32-unknown-unknown --toolchain nightly
rustc +nightly --target wasm32-unknown-unknown -O hello.rs
like image 186
ColinE Avatar answered Nov 01 '22 16:11

ColinE