Compiling to the web with Rust and emscripten

Yes I know, when calling into WebGL or WebAudio this is inevitable though, this is also where the emscripten HTML5 API shims need to maintain actual Javascript objects. It's still quite fast though, around 10k WebGL calls per frame while maintaining 60Hz is possible on desktop (not on mobile though). Still it would be nice to have some sort of 'fast path' in later WebAssembly versions there.

This is so, so cool. I've been interested in Emscripten for a while now, but never actually got in and started working with it.

I spent a few hours yesterday stepping through the generated JavaScript code and was amazed at how it all worked. It's got an emulated Filesystem, Syscalls, Stack, Heap, everything! It's truly incredible that all of this is possible and so easy to get started with - thanks so much for this great writeup!

3 Likes

So I followed the commands above on Windows, and everything works up to:

rustc --target=asmjs-unknown-emscripten hello.rs

Which returns:

error: Could not create LLVM TargetMachine for triple: asmjs-unknown-emscripten: No available targets are compatible with this triple.

But when I run rustup show I get:

installed targets for active toolchain
--------------------------------------

asmjs-unknown-emscripten
wasm32-unknown-emscripten
x86_64-pc-windows-msvc

So I'm not sure where to go next. (I also apologize if this isn't the right thread to ask this, but I haven't found much information on this online and this was the most helpful guide!)

1 Like

What happens is that java and javac on Sierra are stubs: they linger around and once they get called, the prompt will appear.

The problem is that this leads to misdetections of whether java is available or not.

Is the shell you are calling it from configured with the emsdk environment? rustc needs to find emcc and without that it does not have any idea where.

Yeah, I did eventually figure it out (see here). It ended up being that I had an old version of rustc and then a PATH issue with emcc.

So I get it to compile and run in asm.js. When it comes to wasm it compiles but I get the following error. (just doing the Hello, Emscripten demo on this page).

        C:\Users\unsername\rust_test\src\hello.js:110
              throw ex;
              ^
        no binaryen method succeeded. consider enabling more options,
        like interpreting, if you want that: 
        https://github.com/kripken/emscripten/wiki/WebAssembly#binaryen-methods

does anyone have any ideas?

What about source maps? is it possible to compile it for debugging?

the compiled js file is so big, 1.1M here. Can it be optimized?

If someone's interested, I recently gave a talk sharing my experiments with Rust <-> JavaScript interop.

Slides: Rust ⇋ JavaScript
Video: Ingvar Stepanyan - Interaction with real-world JavaScript from compiled Rust - YouTube

9 Likes

Sorry guys, what is the state of Web Workers now? I tried to write something to spawn a web worker thread but no luck.

I posted the details here: Creating web worker from Rust with Emscripten target - Stack Overflow

1 Like

no response
when execute rustc --target=wasm32-unknown-emscripten hello.rs

@brson I have the same question as @eminence RE: building a library. Is there a way to do this?

In my case, I'm building a dynamic lib that will be used with a Unity project -- so that means supporting ALL the platforms. I have it working for everything except asmjs. My crate-type is "cdylib" in my Cargo.toml, but when I try to build for emscripten, it gives me an error that cdylib isn't supported.

2 Likes

From what I understand, asm.js is basically just using JS as a middleman to pass through executable code. The only reason, per se, that JS is necessary is because it is in browsers, and everybody uses browsers. I understand the decision to make emscripten, and thus makes sense to support rust. If it gets people using Rust in place of JS, then that's great. (I like JS and Rust both.)

It seems a little funny to me to just hijack the JS runtime to run an executable, when people can just download an .exe/.bin like normal with better performance.

I do have a heroku nodejs spun up with an emscripten project. It's running a WebGL video game in the browser. So it's an interesting and impressive technology, if not a novelty of virtualization.

Seems more sensical to put a JS runtime in an executable, not the other way around. It's probably too late. I'm sure somebody has already done that and then ran it in asm so we could have emsception.

So, what kind of projects are you all doing with this? Where do you see this going?

1 Like

While I prefer native apps, everybody with their own preference and performance requirements.

asm.js is not passed to an "executable", it is run by the browser's JavaScript Engine(V8 in Chrome for example).

Running inside the browser is more portable(it is easier for a company to iterate and update the software when it is deployed on a website vs an installed binary that needs to be compiled for a specific platform and also people need to manually copy and install it), in some cases people prefer to just open a web-page instead of downloading an app(GMail is a good example here). Chromium OS, etc...

Why would somebody want to use it?: to replace JavaScript code with high-performance, cross-compiled code.
Here is one interesting, relevant to this question, older Rust experiment: https://davidmcneil.github.io/the-rusty-web/

1 Like

What happens if we try to use std::thread::spawn in Rust then try to compile to wasm? Will it just fail?

You will still have a performance hit when you try to interact with the DOM though due to various FFI overheads. But I'm unsure how big a hit that is, or if it would prevent building such a framework in Rust.

@jer Is the source of the examples available? The link https://www.hellorust.com/emscripten/ is now broken.

A question for everyone: do you still use wasm32-unknown-emscripten? The community seems to be moving onto wasm32-unknown-unknown, and at least I couldn't get wasm32-unknown-emscripten to work with the latest stable Rust and current Emscripten SDK: What is a known working setup for using Rust with emscripten (wasm32-unknown-emscripten)?

Most examples should be available on the main page: https://www.hellorust.com/
However it's unmaintained and unchanged for too long now and also focused on wasm32-unknown-unknown only.

Site deprecation, check out RustWasm

Jan 22, 2019 - Jan-Erik Rediger

This site hasn't been updated in over a year. Since then a lot of stuff happened in Rust and the WebAssembly world. The Rust and WebAssembly working...

:rofl:

New page is https://rustwasm.github.io/