7

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?

2
  • Hah, a week of searching and I find nothing. Then minutes after posting this question I find this which may answer it. Will report back once I test it out. Commented Oct 10, 2017 at 2:58
  • In this file pretty much everything about Rust's emscripten target is defined. And here, the comment says that one can add targets by writing a JSON file (without recompiling rustc!). So you could try that to add a custom target which passes the SIDE_MODULE flag to emcc. I would write a proper answer, but I don't have time right now. Sorry :< Commented Oct 10, 2017 at 7:37

1 Answer 1

6

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
Sign up to request clarification or add additional context in comments.

2 Comments

I've just spotted, there's a toolkit built around this concept github.com/dcodeIO/webassembly
@Shepmaster fair point - I've completely re-written the answer

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.