Skip to content

Commit 2747012

Browse files
authored
Merge pull request #71 from derivator/html5-guide
Add HTML5 export guide
2 parents f7bce47 + b4dbde4 commit 2747012

File tree

2 files changed

+115
-0
lines changed

2 files changed

+115
-0
lines changed

src/SUMMARY.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
- [Android](./exporting/android.md)
4040
- [(TODO) iOS](./exporting/ios.md)
4141
- [Mac OS X](./exporting/macosx.md)
42+
- [HTML5](./exporting/html5.md)
4243
- [Advanced Guides](./advanced-guides.md)
4344
- [Using custom Godot versions](./advanced-guides/custom-godot.md)
4445
- [Migrating from godot-rust 0.8](advanced-guides/migrating-0-8.md)

src/exporting/html5.md

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
# HTML5
2+
3+
Exporting to HTML5 works just like exporting to other platforms, however there are some things that can make the process a bit tricky and require extra attention.
4+
5+
## What you need (to know)
6+
7+
The Godot HTML5 export templates are built with [Emscripten](https://emscripten.org/), so you need to build your Rust code for the `wasm32-unknown-emscripten` target (`wasm32-unknown-unknown` will not work).
8+
Since Emscripten does not offer a stable ABI between versions, your code and the Godot export template have to be built with the same Emscripten version, which also needs to be compatible with the Rust compiler version you are using.
9+
In practice, this means you probably have to do some or all of these things:
10+
* install a specific version of Emscripten
11+
* [build the HTML5 export template yourself](https://docs.godotengine.org/en/stable/development/compiling/compiling_for_web.html)
12+
* use a specific version of Rust
13+
14+
You can check which versions of Emscripten/Rust you are using like this:
15+
16+
```bash
17+
emcc -v
18+
rustc --version --verbose
19+
```
20+
21+
A version mismatch between Rust and Emscripten will probably result in compiler errors, while using incompatible Emscripten versions between Rust and Godot will result in cryptic runtime errors.
22+
23+
Emscripten uses a cache to store build artifacts and header files. In some cases this means that the order in which steps are completed matters.
24+
25+
Also note that `wasm32-unknown-emscripten` is a 32-bit target, which can cause problems with crates incorrectly assuming that `usize` is 64 bits wide.
26+
27+
## Godot 3.5
28+
29+
**Disclaimer**: _Currently, the following steps are only tested and confirmed to work on Linux._
30+
31+
[Godot 3.5's prebuilt HTML5 export template is built with Emscripten 3.1.10](https://github.com/godotengine/godot/blob/3.5/.github/workflows/javascript_builds.yml).
32+
It might be possible to use it if build your Rust code with that exact version, but extra compiler flags may be needed. This guide focuses on building the export template yourself with a recent version of Emscripten.
33+
As of 2022-09-04 you also need to use a Rust nightly build.
34+
35+
Confirmed working versions are:
36+
* rustc 1.65.0-nightly (8c6ce6b91 2022-09-02)
37+
* Emscripten 3.1.21-git (3ce1f726b449fd1b90803a6150a881fc8dc711da)
38+
39+
40+
### Installing and configuring Emscripten
41+
42+
We will be using the most recent git version of Emscripten (tip-of-tree):
43+
44+
```bash
45+
# Get the emsdk repo
46+
git clone https://github.com/emscripten-core/emsdk.git
47+
48+
# Enter that directory
49+
cd emsdk
50+
51+
# Download and install the tip-of-tree SDK tools.
52+
./emsdk install tot
53+
54+
# Make the "tot" SDK "active" for the current user. (writes .emscripten file)
55+
./emsdk activate tot
56+
57+
# Activate PATH and other environment variables in the current terminal
58+
source ./emsdk_env.sh
59+
```
60+
61+
### Building Godot
62+
63+
Build the Godot Export template according to the [instructions](https://docs.godotengine.org/en/stable/development/compiling/compiling_for_web.html):
64+
65+
```bash
66+
source "/path/to/emsdk-portable/emsdk_env.sh"
67+
scons platform=javascript tools=no gdnative_enabled=yes target=release
68+
mv bin/godot.javascript.opt.gdnative.zip bin/webassembly_gdnative_release.zip
69+
```
70+
71+
Set the newly built export template as a [custom template](https://user-images.githubusercontent.com/2171264/175822720-bcd2f1ff-0a1d-4495-9f9c-892d42e9bdcd.png) in Godot and be sure to set the export type as GDNative. When exporting, uncheck "Export With Debug".
72+
73+
### Building your Rust code
74+
75+
In your project's `config.toml`, add the following:
76+
77+
```toml
78+
[target.wasm32-unknown-emscripten]
79+
rustflags = [
80+
"-Clink-arg=-sSIDE_MODULE=2", # build a side module that Godot can load
81+
"-Zlink-native-libraries=no", # workaround for a wasm-ld error during linking
82+
"-Cpanic=abort", # workaround for a runtime error related to dyncalls
83+
]
84+
```
85+
86+
Build like this:
87+
88+
```bash
89+
source "/path/to/emsdk-portable/emsdk_env.sh"
90+
export C_INCLUDE_PATH=$EMSDK/upstream/emscripten/cache/sysroot/include
91+
92+
cargo +nightly build --target=wasm32-unknown-emscripten --release
93+
```
94+
95+
The result is a `.wasm` file that you add in your `GDNativeLibrary` properties under `entry/HTML5.wasm32`, just like you would add a `.so` or a `.dll` for Linux or Windows.
96+
97+
### Errors you might encounter
98+
99+
Compile time:
100+
* `failed to run custom build command for gdnative-sys v0.10.1`, `fatal error: 'wchar.h' file not found`: Emscripten cache not populated, build Godot export template first
101+
* `undefined symbol: __cxa_is_pointer_type`: You need to build with `-Clink-arg=-sSIDE_MODULE=2`
102+
103+
Runtime:
104+
* `indirect call signature mismatch`: Possibly due to Emscripten version mismatch between Godot and Rust
105+
* `need the dylink section to be first`: Same as above
106+
* `WebAssembly.Module(): Compiling function #1 failed: invalid local index`: You need to build with `-Cpanic=abort`
107+
108+
### Further reading
109+
110+
In the future, some of this will probably not be needed, for more info see:
111+
* [Tracking issue for godot-rust wasm support](https://github.com/godot-rust/godot-rust/issues/647)
112+
* [Rust](https://github.com/rust-lang/rust/issues/98155) and [Emscripten](https://github.com/rust-lang/rust/pull/98303#issuecomment-1162172132) issues that explain the need for `-Zlink-native-libraries=no`
113+
* [Emscripten PR that should have obsoleted `-Cpanic=abort`](https://github.com/emscripten-core/emscripten/pull/17328)
114+
* [Rust PR that would obsolete `-Clink-arg=-sSIDE_MODULE=2`](https://github.com/rust-lang/rust/pull/98358)

0 commit comments

Comments
 (0)