I was following instructions from https://users.rust-lang.org/t/compiling-to-the-web-with-rust-and-emscripten/7627 and had no luck in generating working example.
no binaryen method succeeded. consider enabling more options, like interpreting, if you want that: https://github.com/kripken/emscripten/wiki/WebAssembly#binaryen-methods
Memory property of WebAssembly object"Hello, Emscripten!" string anywhereindex.html with such content:<script type='text/javascript'>
fetch('hello.wasm')
.then(response => response.arrayBuffer())
.then(buffer => WebAssembly.compile(buffer))
.then(console.log)
</script>
and ran Python's SimpleHTTPServer. Running this in latest Chrome Canary with WebAssembly enabled doesn't do anything while not throwing errors and showing an empty wasm module object.
So I'm not sure if Rust code cross-compiles to correct wasm module at all for now (using rustc 1.14.0 and emcc 1.37.0 / 1.37.1). Am I doing something wrong?
@kripken's answer (from here)
In general you can open an issue on the binaryen tracker (often it's the right place, if not that's fine too). Regarding your issues:
- Yes, node.js doesn't have wasm support yet. You can use SpiderMonkey or V8 shells (very latest versions), or nightly/canary versions of the browsers. Or, enable the interpreter, which will work everywhere.
- You should see the string in the wast, that is surprising. It should be in the memory segments, near the top of the file. Are there no memory segments? Earlier binaryen versions didn't use them, but we should now.
- You can't load the wasm by yourself - it isn't standalone (there is work towards standalone wasm, which perhaps rust can use eventually). The JS code knows how to load it and run it. Try to just create an html page with in it.
@kripken I've tried to run generated JS file in browser and there is an error
Assertion failed: on the web, we need the wasm binary to be preloaded and set on Module['wasmBinary']. emcc.py will do that for you when generating HTML (but not JS)
Also there is no "Hello, Emscripten!" in generated JS file. And there are no memory segments in wast as far as I can see.
Rust source file:
Generated files:
I think the string is in the (data line, it's just encoded so it doesn't look normal. If you open the wasm (binary) in an editor, though, you will see it.
For that assertion, we should be improving it soon, but meanwhile if you can emit HTML instead of JS, it will work (the html will set up the binary for you; alternatively, you can set it up yourself manually).
Thank you for your answer!
In fact my goal is to create a wasm module (using Rust) with simple function exported to use from JS via JavaScript API in Canary / FF Nightly
Maybe there are some articles / docs / blog posts which can help?
BTW, how can I emit HTML? Should I call rustc with some Binaryen flags passed to it somehow?
Sorry for my newbie questions :(
To emit html, you just call emcc with -o output.html, the suffix tells it what to emit. Not sure where that fits in with rustc though.
If all you want is a wasm module that you use directly, and it doesn't need JS integration, and it doesn't need libc or other system libs (which often needs JS, e.g. to print), then you can read the "standalone wasm". It has a full example, that maybe you can connect rustc to? But the standalone stuff is experimental, so expect breakage.
To emit html, you just call emcc with -o output.html, the suffix tells it what to emit. Not sure where that fits in with rustc though.
It was as simple as
rustc --target=wasm32-unknown-emscripten hello.rs -o output.html
馃帀
it doesn't need libc or other system libs
I just need arithmetic operations without any I/O. Standalone wasm is exactly what I need. Thank you! I'll try it.
@brson is there any way to pass -s option to emcc? I believe that -s "BINARYEN_METHOD='interpret-binary'" should be passed to run compiled JS in Node.js
@chicoxyzzy no i don't think so, this is the same old tired issue of not being able to pass link arguments to the "system" linker (in this case emcc) via cargo.
Of course, you can:
-vv-s "BINARYEN_METHOD='interpret-binary'" to the "link line"Alternatively, you can perform some path hackery and have emcc automatically pass -s
PS: your your suggestion works by the way, thank you, I couldn't seem to find this mentioned anywhere obviously...