如何使用Rust生成最小的wasm文件?

时间:2017-10-10 02:44:58

标签: rust webassembly

我可以通过运行#include <emscripten/emscripten.h> int EMSCRIPTEN_KEEPALIVE sum(int a, int b) { return a + b; } 从以下C代码生成一个相当小的(203字节)wasm文件。

(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 ...
)

反汇编输出:

pub fn main() {}

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

但是给出了以下Rust代码

rustc -O --target=wasm32-unknown-emscripten sum.rs

我似乎无法产生类似的东西。

EMMAKEN_CFLAGS='-s WASM=1 -s SIDE_MODULE=1'有效但给了我一个85k的wasm文件和一个128k的js文件。

我已尝试导出1.22.0-nightly (c6884b12d 2017-09-30),但这会给我一些警告,例如

  

输入文件&#34; / tmp /.../ rust.metadata.bin&#34;存在,但不是适用于Emscripten的LLVM bitcode文件。也许意外地将本机构建的目标文件与Emscripten混合在一起?

然后无法链接。

我的Rust版本为1.37.21,我的emcc版本为/data/app/

我做错了什么?

1 个答案:

答案 0 :(得分:5)

使用wasm32-unknown-emscripten目标,您正在使用基于Emscripten的编译器工具链。 Emscripten在wasm模块中添加了相当多的额外运行时代码,以及用于在运行时与此集成的其他JavaScript代码。正如您所观察到的,Emscripten可以使用SIDE_MODULE选项进行编译,从而删除绝大多数此运行时代码。这减少了wasm二进制文件的大小,但意味着你必须自己处理诸如绑定复杂类型之类的事情。

最近(2017年11月)一个新的wasm32-unknown-unknown target was added to Rust,它使用LLVM后端(而不是Emscripten及其fastcomp fork),从而产生最小的输出。

可以按照setup guide

中的说明使用此目标
rustup update
rustup target add wasm32-unknown-unknown --toolchain nightly
rustc +nightly --target wasm32-unknown-unknown -O hello.rs