From c1e206f57dae7435090e16abc1f17b4386811874 Mon Sep 17 00:00:00 2001 From: derivator Date: Sat, 25 Jun 2022 20:08:42 +0200 Subject: [PATCH 1/3] Add HTML5 export guide --- src/SUMMARY.md | 1 + src/exporting/html5.md | 92 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 93 insertions(+) create mode 100644 src/exporting/html5.md diff --git a/src/SUMMARY.md b/src/SUMMARY.md index b22281f..2b9956b 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -39,6 +39,7 @@ - [Android](./exporting/android.md) - [(TODO) iOS](./exporting/ios.md) - [Mac OS X](./exporting/macosx.md) + - [HTML5](./exporting/html5.md) - [Advanced Guides](./advanced-guides.md) - [Using custom Godot versions](./advanced-guides/custom-godot.md) - [Migrating from godot-rust 0.8](advanced-guides/migrating-0-8.md) diff --git a/src/exporting/html5.md b/src/exporting/html5.md new file mode 100644 index 0000000..305cd24 --- /dev/null +++ b/src/exporting/html5.md @@ -0,0 +1,92 @@ +# HTML5 + +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. + +## General considerations + +The Godot HTML5 export templates are built with [Emscripten](https://emscripten.org/), so you need to build your code for the `wasm32-unknown-emscripten` target, `wasm32-unknown-unknown` will not work. Furthermore, you need to use a version of emscripten that is compatible with both your version of Rust and the version of emscripten used to build the export template. +In practice, this means you might have to [build the HTML5 export template yourself](https://docs.godotengine.org/en/stable/development/compiling/compiling_for_web.html) and/or use a specific version of Rust. You can check which versions you are using like this: + +```bash +emcc -v +rustc --version --verbose +``` + +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. + +## Godot 3.4.4 + +**Disclaimer**: _Currently, the following steps are only tested and confirmed to work on Linux._ + +Godot 3.4.4's export template is built with a very old Emscripten version that doesn't play nice with Rust. We will have to build it ourselves with a more recent version. +We also need to build the `std` crate ourselves, so we will have to use a nightly Rust build. + +Confirmed working versions are: +* rustc 1.63.0-nightly (dc80ca78b 2022-06-21) +* Emscripten 3.1.15-git (4100960b42619b28f19baf4254d5db2097234b32) + + +### Getting Emscripten + +We will be using Emscripten tip-of-tree: + +```bash +# Get the emsdk repo +git clone https://github.com/emscripten-core/emsdk.git + +# Enter that directory +cd emsdk + +# Download and install the tip-of-tree SDK tools. +./emsdk install tot + +# Make the "tot" SDK "active" for the current user. (writes .emscripten file) +./emsdk activate tot + +# Activate PATH and other environment variables in the current terminal +source ./emsdk_env.sh +``` + +### Building Godot + +Build the Godot Export template according to the [instructions](https://docs.godotengine.org/en/stable/development/compiling/compiling_for_web.html): + +```bash +source "/path/to/emsdk-portable/emsdk_env.sh" +scons platform=javascript tools=no gdnative_enabled=yes target=release +mv bin/godot.javascript.opt.gdnative.zip bin/webassembly_gdnative_release.zip +``` + +Set the newly built export template as a custom template in Godot and be sure to set the export type as GDNative. When exporting, uncheck "Export With Debug". + +### Building your Rust code + +In your project's `config.toml`, add the following: + +```toml +[target.wasm32-unknown-emscripten] +rustflags = [ + "-Clink-arg=-sSIDE_MODULE=2", # build a side module that Godot can load + "-Crelocation-model=pic", # needed to prevent linker errors + "-Cpanic=abort", # panic unwinding is currently broken without -sWASM_BIGINT, see below + #"-Clink-arg=-sWASM_BIGINT", # alternative to panic=abort, requires building godot with -sWASM_BIGINT also +] +``` + +Build like this: + +```bash +source "/path/to/emsdk-portable/emsdk_env.sh" +export C_INCLUDE_PATH=$EMSDK/upstream/emscripten/cache/sysroot/include + +cargo +nightly build --target=wasm32-unknown-emscripten --release -Zbuild-std=core,std,alloc,panic_abort +``` + +### Further reading + +In the future, some/all of this will probably not be needed, for more info see: +* [Tracking issue for godot-rust wasm support](https://github.com/godot-rust/godot-rust/issues/647) +* [Rust PR that obsoletes -Clink-arg=-sSIDE_MODULE=2](https://github.com/rust-lang/rust/pull/98358) +* [Rust PR that obsoletes -Crelocation-model=pic and -Zbuild-std](https://github.com/rust-lang/rust/pull/98149) +* [Godot PR that updates Emscripten version](https://github.com/godotengine/godot/pull/61989) +* [Godot PR that would obsolete -Cpanic=abort in favor of -sWASM_BIGINT](https://github.com/godotengine/godot/pull/62397) \ No newline at end of file From 1112ad9fa6fb587093ede1fed9133d1579f3bec0 Mon Sep 17 00:00:00 2001 From: derivator Date: Mon, 4 Jul 2022 14:02:35 +0200 Subject: [PATCH 2/3] Update HTML5 export guide to reflect current state of affairs --- src/exporting/html5.md | 41 +++++++++++++++++++++++++---------------- 1 file changed, 25 insertions(+), 16 deletions(-) diff --git a/src/exporting/html5.md b/src/exporting/html5.md index 305cd24..438fe13 100644 --- a/src/exporting/html5.md +++ b/src/exporting/html5.md @@ -2,33 +2,41 @@ 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. -## General considerations +## What you need (to know) -The Godot HTML5 export templates are built with [Emscripten](https://emscripten.org/), so you need to build your code for the `wasm32-unknown-emscripten` target, `wasm32-unknown-unknown` will not work. Furthermore, you need to use a version of emscripten that is compatible with both your version of Rust and the version of emscripten used to build the export template. -In practice, this means you might have to [build the HTML5 export template yourself](https://docs.godotengine.org/en/stable/development/compiling/compiling_for_web.html) and/or use a specific version of Rust. You can check which versions you are using like this: +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). +You need to build your code with a version of Emscripten that is compatible with your version of Rust and (ideally identical to) the version of Emscripten used to build the export template. +In practice, this means you might have to: +* install a specific version of Emscripten +* [build the HTML5 export template yourself](https://docs.godotengine.org/en/stable/development/compiling/compiling_for_web.html) +* use a specific version of Rust + +You can check which versions of Emscripten/Rust you are using like this: ```bash emcc -v rustc --version --verbose ``` +A version mismatch between Rust and Emscripten will probably result in compiler errors, while incompatible Emscripten versions between Rust and Godot will result in cryptic runtime errors such as `indirect call signature mismatch`. + 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. ## Godot 3.4.4 **Disclaimer**: _Currently, the following steps are only tested and confirmed to work on Linux._ -Godot 3.4.4's export template is built with a very old Emscripten version that doesn't play nice with Rust. We will have to build it ourselves with a more recent version. -We also need to build the `std` crate ourselves, so we will have to use a nightly Rust build. +Godot 3.4.4's export template is built with a very old Emscripten version that doesn't play nice with Rust. You will have to build it yourself with a more recent version. +As of 2022-07-02 you also need to use a Rust nightly build. Confirmed working versions are: -* rustc 1.63.0-nightly (dc80ca78b 2022-06-21) -* Emscripten 3.1.15-git (4100960b42619b28f19baf4254d5db2097234b32) +* rustc 1.64.0-nightly (f2d93935f 2022-07-02) +* Emscripten 3.1.16-git (e026c0e22a986d92695b2563a1e8ef140b5d8a87) -### Getting Emscripten +### Installing and configuring Emscripten -We will be using Emscripten tip-of-tree: +We will be using the most recent git version of Emscripten (tip-of-tree): ```bash # Get the emsdk repo @@ -57,7 +65,7 @@ scons platform=javascript tools=no gdnative_enabled=yes target=release mv bin/godot.javascript.opt.gdnative.zip bin/webassembly_gdnative_release.zip ``` -Set the newly built export template as a custom template in Godot and be sure to set the export type as GDNative. When exporting, uncheck "Export With Debug". +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". ### Building your Rust code @@ -67,7 +75,6 @@ In your project's `config.toml`, add the following: [target.wasm32-unknown-emscripten] rustflags = [ "-Clink-arg=-sSIDE_MODULE=2", # build a side module that Godot can load - "-Crelocation-model=pic", # needed to prevent linker errors "-Cpanic=abort", # panic unwinding is currently broken without -sWASM_BIGINT, see below #"-Clink-arg=-sWASM_BIGINT", # alternative to panic=abort, requires building godot with -sWASM_BIGINT also ] @@ -79,14 +86,16 @@ Build like this: source "/path/to/emsdk-portable/emsdk_env.sh" export C_INCLUDE_PATH=$EMSDK/upstream/emscripten/cache/sysroot/include -cargo +nightly build --target=wasm32-unknown-emscripten --release -Zbuild-std=core,std,alloc,panic_abort +cargo +nightly build --target=wasm32-unknown-emscripten --release ``` +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. + ### Further reading In the future, some/all of this will probably not be needed, for more info see: * [Tracking issue for godot-rust wasm support](https://github.com/godot-rust/godot-rust/issues/647) -* [Rust PR that obsoletes -Clink-arg=-sSIDE_MODULE=2](https://github.com/rust-lang/rust/pull/98358) -* [Rust PR that obsoletes -Crelocation-model=pic and -Zbuild-std](https://github.com/rust-lang/rust/pull/98149) -* [Godot PR that updates Emscripten version](https://github.com/godotengine/godot/pull/61989) -* [Godot PR that would obsolete -Cpanic=abort in favor of -sWASM_BIGINT](https://github.com/godotengine/godot/pull/62397) \ No newline at end of file +* [Rust PR that would obsolete `-Clink-arg=-sSIDE_MODULE=2`](https://github.com/rust-lang/rust/pull/98358) +* [Godot PR that updates Emscripten version for Godot 3.x](https://github.com/godotengine/godot/pull/61989) +* [Godot PR that would obsolete `-Cpanic=abort` in favor of `-sWASM_BIGINT`](https://github.com/godotengine/godot/pull/62397) +* [Emscripten PR that would obsolete `-Cpanic=abort` without requiring `-sWASM_BIGINT`](https://github.com/emscripten-core/emscripten/pull/17328) \ No newline at end of file From b4dbde4a9e53efedbb260182b493146115a7b97d Mon Sep 17 00:00:00 2001 From: derivator Date: Sun, 4 Sep 2022 13:25:08 +0200 Subject: [PATCH 3/3] Update HTML5 export guide for Godot 3.5 Recommend building Godot export template yourself, always Remove mention of WASM_BIGINT as alternative to panic=abort --- src/exporting/html5.md | 41 +++++++++++++++++++++++++++-------------- 1 file changed, 27 insertions(+), 14 deletions(-) diff --git a/src/exporting/html5.md b/src/exporting/html5.md index 438fe13..111582c 100644 --- a/src/exporting/html5.md +++ b/src/exporting/html5.md @@ -5,8 +5,8 @@ Exporting to HTML5 works just like exporting to other platforms, however there a ## What you need (to know) 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). -You need to build your code with a version of Emscripten that is compatible with your version of Rust and (ideally identical to) the version of Emscripten used to build the export template. -In practice, this means you might have to: +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. +In practice, this means you probably have to do some or all of these things: * install a specific version of Emscripten * [build the HTML5 export template yourself](https://docs.godotengine.org/en/stable/development/compiling/compiling_for_web.html) * use a specific version of Rust @@ -18,20 +18,23 @@ emcc -v rustc --version --verbose ``` -A version mismatch between Rust and Emscripten will probably result in compiler errors, while incompatible Emscripten versions between Rust and Godot will result in cryptic runtime errors such as `indirect call signature mismatch`. +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. + +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. 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. -## Godot 3.4.4 +## Godot 3.5 **Disclaimer**: _Currently, the following steps are only tested and confirmed to work on Linux._ -Godot 3.4.4's export template is built with a very old Emscripten version that doesn't play nice with Rust. You will have to build it yourself with a more recent version. -As of 2022-07-02 you also need to use a Rust nightly build. +[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). +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. +As of 2022-09-04 you also need to use a Rust nightly build. Confirmed working versions are: -* rustc 1.64.0-nightly (f2d93935f 2022-07-02) -* Emscripten 3.1.16-git (e026c0e22a986d92695b2563a1e8ef140b5d8a87) +* rustc 1.65.0-nightly (8c6ce6b91 2022-09-02) +* Emscripten 3.1.21-git (3ce1f726b449fd1b90803a6150a881fc8dc711da) ### Installing and configuring Emscripten @@ -75,8 +78,8 @@ In your project's `config.toml`, add the following: [target.wasm32-unknown-emscripten] rustflags = [ "-Clink-arg=-sSIDE_MODULE=2", # build a side module that Godot can load - "-Cpanic=abort", # panic unwinding is currently broken without -sWASM_BIGINT, see below - #"-Clink-arg=-sWASM_BIGINT", # alternative to panic=abort, requires building godot with -sWASM_BIGINT also + "-Zlink-native-libraries=no", # workaround for a wasm-ld error during linking + "-Cpanic=abort", # workaround for a runtime error related to dyncalls ] ``` @@ -91,11 +94,21 @@ cargo +nightly build --target=wasm32-unknown-emscripten --release 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. +### Errors you might encounter + +Compile time: +* `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 +* `undefined symbol: __cxa_is_pointer_type`: You need to build with `-Clink-arg=-sSIDE_MODULE=2` + +Runtime: +* `indirect call signature mismatch`: Possibly due to Emscripten version mismatch between Godot and Rust +* `need the dylink section to be first`: Same as above +* `WebAssembly.Module(): Compiling function #1 failed: invalid local index`: You need to build with `-Cpanic=abort` + ### Further reading -In the future, some/all of this will probably not be needed, for more info see: +In the future, some of this will probably not be needed, for more info see: * [Tracking issue for godot-rust wasm support](https://github.com/godot-rust/godot-rust/issues/647) +* [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` +* [Emscripten PR that should have obsoleted `-Cpanic=abort`](https://github.com/emscripten-core/emscripten/pull/17328) * [Rust PR that would obsolete `-Clink-arg=-sSIDE_MODULE=2`](https://github.com/rust-lang/rust/pull/98358) -* [Godot PR that updates Emscripten version for Godot 3.x](https://github.com/godotengine/godot/pull/61989) -* [Godot PR that would obsolete `-Cpanic=abort` in favor of `-sWASM_BIGINT`](https://github.com/godotengine/godot/pull/62397) -* [Emscripten PR that would obsolete `-Cpanic=abort` without requiring `-sWASM_BIGINT`](https://github.com/emscripten-core/emscripten/pull/17328) \ No newline at end of file