-
Notifications
You must be signed in to change notification settings - Fork 212
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support wasm32-unknown-emscripten target #647
Comments
Unfortunately, this cannot be done right now since Rust is still using LLVM 11, which is no longer supported by the version of emscripten that Godot requires (2.0.10). Rust only updates LLVM on new releases, so we'll have to wait for a few months until LLVM is updated upstream. Until then, it might be a good idea to clarify the state of WASM support in documentation. |
Any updates on this? |
@deep-gaurav Not yet, still blocked by rustc :( |
With Version 1.52 we got LLVM 12 Support: https://github.com/rust-lang/rust/blob/master/RELEASES.md#version-1520-2021-05-06 |
Just FYI I successfully compiled for wasm with various hacks : https://github.com/orion78fr/godot_keepass_rust_totp |
@orion78fr That's wonderful! Last time I checked there was some miscompilation around |
I've put the repository under MIT License, that should be OK. Some things I had to do :
Maybe something else, I don't remember x) |
@orion78fr Thanks. The workflow file is very helpful! |
@orion78fr thanks so much for looking into this. did you try to run your Web export in safari? on Firefox, chrome it seems to work fine. I have the same issue with my demo, so I was wondering |
Yeah I only tested Chrome / Firefox on Windows and Android (as I mainly focus on APK export atm, can't figure out how I could make Android java calls to open files). Seems like it's some part of the specs that are not supported on Safari. CanIuse list shared memory as not supported, but I don't know if it's this in particular. Note that I had emcc complaining about shared memory though so maybe it's this. |
@orion78fr I can export a regular WebGL app via godot and it runs in the browser: https://jontopielski.itch.io/puzzle-sigma (just an example) so I am still a little hopeful we can figure out how to build a gdnative lib so that safari can load it aswell - after all the above shows that godot itself manages to compile to something safari is able to take and run. it must be some crazy param that i am missing to pass to |
whatever I do once I run
which does not happen on any of the Wasm files godot produces. after a little digging validate works once I pass: |
(Oh I've seen this one featured in the GMTK jam 2021 video !) Yeah probably, but I think that I'm missing some flags to pass to The dynamic lib ABI is still in a WIP state though : https://github.com/WebAssembly/tool-conventions/blob/master/DynamicLinking.md I've read somewhere that iOS doesn't even support dynamic libs and that GDNative lib should be statically linked, maybe we could do something similar and produce a binary with both godot and out GDNative lib ? |
Try removing |
Hi! I just arrived after googling a few hours... Is there a "one-line" command to do the same as you have in the build? (I'm on archlinux) I tried several things but I end with the error:
I setted the clang lib with I tries to build for wasm32-unknown-unknown and I have the same error with the header... |
yeah that gives us:
so the question is: can we make rust not emit mutable-globals (maybe via https://releases.llvm.org/10.0.0/tools/clang/docs/ClangCommandLineReference.html#cmdoption-clang-mmutable-globals)? |
@orion78fr oooor reading this maybe we can advance here not exporting all functions |
@cristomc I think you are missing the include path from emscripten ( |
A little followup: I figured out all the emscripten specific rust flags using:
so by passing |
Can you try adding |
I tried all that :D, seems all features are off by default. but I got it to run. let me cleanup and see which of the thousand changes actually were needed, then I will post that here🥳 |
Example code of this would really help |
like I said: I am cleaning it up and posting back here... |
Sorry wasn't sure if you meant you were just going to share the flags |
It sure is just about the flags - the rest is unchanged to the repo @orion78fr shared |
Now I can confirm it works on safari aswell, you only need to reduce the optimisation: But this is not where the story ends, I wanted to port two open source godot projects: godot-vs-rapier and rapier-determinism (you can find the exact build calls as makefiles in there aswell) Both make use of After figuring all those out I now have web builds of the above projects!! 🥳 see: Thanks again @orion78fr for kicking this off. A few things that I would like to investigate from here on:
|
Is this stable enough to be added to the Makefile in godot-rust-template? |
Honestly, I'm unsure. It seems very brittle. |
being a emscripten noob I am wondering: is there a way to make godo-web call our gdnative lib compiled to regular wasm? I mean the |
That would have been cool but it seems like godot-rust needs a libc (wchar.h & co), which is what is provided by emscripten IIRC. |
I'm on archlinux (
not sure about how to fix this. |
I've been trying to get this to work on an up-to-date emscripten. Using rust nightly and emscripten tip-of-tree, it seems to be almost working, here's what I've got: @hoodmane figured out some flags that are needed here. [target.wasm32-unknown-emscripten]
rustflags = [
"-Crelocation-model=pic",
"-Clink-arg=-sSIDE_MODULE=2",
"-Clink-arg=-sWASM_BIGINT", #not strictly necessary?
"-Clink-arg=-sDYNCALLS=1", #should fix the issue I'm currently stuck on, but doesn't work
] In the future, these shouldn't be needed anymore. To build: export CARGO_BUILD_TARGET=wasm32-unknown-emscripten
export C_INCLUDE_PATH=$EMSDK/upstream/emscripten/cache/sysroot/include
cargo +nightly build --release -Zbuild-std
The Godot 3.4.4 HTML5 export template is built with an older, incompatible emscripten version, you have to build it yourself according to this. Should be fixed in 3.6 I think. Godot loads the wasm module and function dynCallLegacy(sig, ptr, args) {
var f = Module["dynCall_" + sig];
return args && args.length ? f.apply(null, [ptr].concat(args)) : f.call(null, ptr)
} is called with Emscripten 2.0.13 release notes say:
This looks like it should fix the issue, but I haven't had any luck with it. It also seems that the issue occurs regardless of the |
Unfortunately it looks like we were a day late for the 1.62.0 merge window, but it should make it into 1.63.0 which will probably be at the beginning of August. We may also get fixes into 1.63.0 that make it "just work" so that a cdylib compiled with emscripten target will automatically pass I wrote a blog post on this:
This issue shouldn't happen with the WASM_BIGINT flag. You need to make sure to pass it to both the main module and the side module. But I'm surprised you would get an error like that from passing it only to the side module. I will try building godot-rust and see what the generated code looks like. |
If you are using a precompiled main module which was compiled without WASM_BIGINT, then you can build with this patch applied to Emscripten and the error should go away: |
I confirmed that you will see that error if you compile the side module with |
Holy moly, it works. @hoodmane thanks so much for your help! I had to patch the build script for godot's javascript export template by adding these lines:
|
@hoodmane @derivator (and others in this thread): I have the feeling that this thread contains a lot of very valuable insights, but they're a bit scattered and hard to find for someone new to the topic. On our Discord there have also been a few users tinkering with WASM, maybe they could help as well! |
Out of curiosity, is there a reason you're dynamically linking this? It seems like it would be reasonable to statically link the rust bindings and the engine together for wasm, in particular you'd get faster load times and smaller code size. If that doesn't work for some reason you could also try building the bindings first and passing the so file to the main module and using |
Another approach you might try is setting |
@hoodmane I think that's just how Godot/GDNative works. You define a GDNative library in the editor and provide a .dll/.so/.wasm for Windows/Linux/HTML5 export. I can only speculate why Godot chose dynamic linking, I suspect it's just for developer convenience, so you don't have to link the engine yourself when you export. I don't know if it's possible to use static linking instead (apparently you have to on iPhone because it doesn't allow dynamic linking?), but the default workflow seems to be dynamic linking, so it makes sense to try to support that. |
Emscripten tries to statically link if at all possible -- this is why if you pass
In particular, currently you can only pick one of |
The thing is that Godot usually uses a prebuilt executable for the engine. I don't know if there's even an established workflow for linking a GDNative module statically, though I guess if it's needed for iPhone, it has to exist somewhere... |
For the record, I opened a PR to fix Rust side modules when not using |
I'm a bit confuse, I was able to build and run my project, using tot emscripten + custom godot export template + rust nightly 1.64. I was expecting to see a panic, since I'm using Any idea of how it is possible that |
ooh, right, in emscripten the environment is unix, not wasm, just checked with: cfg_if::cfg_if! {
if #[cfg(unix)] {
godot_print!("env: UNIX");
} else if #[cfg(target_family = "wasm")] {
godot_print!("env: WASM");
} else {
godot_print!("env: OTHER");
}
} and that's using |
There is now a HTML5 guideline in the book. While there's probably still work to do, I would consider this a first step towards WebAssembly support, and thus close this issue. Thanks a lot to everyone who has helped getting there! 👍 |
With WebAssembly support being added to the engine, this should be a priority for the next release.
The text was updated successfully, but these errors were encountered: