Skip to content
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

Add HTML5 export guide #71

Merged
merged 3 commits into from
Sep 4, 2022
Merged

Add HTML5 export guide #71

merged 3 commits into from
Sep 4, 2022

Conversation

derivator
Copy link
Contributor

@Bromeon as discussed in #647 this should cover most of the current problems with HTML5 exports.

Copy link
Contributor

@jacobsky jacobsky left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you so much for the PR! This is a great guide that helps better define how godot-rust supports HTML5 exports.

I have included some minor nitpicks on structure. I will also give this process a go to test this from my end.

@Bromeon feel free to let me know if you have any additional thoughts or questions on this addition


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
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since this export process doesn't have a trivial set up, I think this section can be called "Tooling Requirements", "Setup Requirements" or something like that. This would make it more obvious to users that there are very specific requirements for this export process.


## Godot 3.4.4

**Disclaimer**: _Currently, the following steps are only tested and confirmed to work on Linux._
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It might be worth making this disclaimer into it's own section where we can include all of the additional version requirements. In the future, more folks may be able to test this and confirm working versions so having a section could be useful for new users.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I expect this whole section to become outdated very rapidly. What I said under "General Considerations" (matching emscripten versions) is fairly general, but building Godot will probably not be necessary with 3.6, and rust compiler flags could change any second now.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fair point. I think keeping a normal disclaimer is probably enough in that case.

* Emscripten 3.1.15-git (4100960b42619b28f19baf4254d5db2097234b32)


### Getting Emscripten
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor nitpick, "Installing and configuring Emscripten" might be a more appropriate section title.

source ./emsdk_env.sh
```

### Building Godot
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this require building Godot from source? or only the export template? If the latter, can we change the title to "Building Godot export template"

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As far as I can tell an export template is just a pre-built version of Godot, so these are the same thing. We are compiling the engine from source to wasm.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since you built Godot from source, did you use gdnative with the custom-godot Cargo feature?

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".
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm assuming that the export template requires installing from a file as per: https://docs.godotengine.org/en/stable/tutorials/export/exporting_basics.html#export-templates

Is that correct? If so, can I ask for you to add the above link for completeness?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is what I'm referring to:
image

We could link that image?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds good to me!

Copy link
Member

@Bromeon Bromeon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is an awesome addition, thank you very much! ❤️

Good that you highlighted that some of the guide might be obsolete soon. I think it's good to start somewhere, and update when needed. Hopefully, a smaller scale in updating also motivates more people to contribute 🙂

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".
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds good to me!


### Building your Rust code

In your project's `config.toml`, add the following:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This refers to the godot-rust crate which is compiled as a cdylib? If yes, maybe quickly mention that to resolve ambiguities 🙂

source ./emsdk_env.sh
```

### Building Godot
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since you built Godot from source, did you use gdnative with the custom-godot Cargo feature?

@Bromeon Bromeon added the new-topic A new topic to be added has been requested label Jun 26, 2022
@derivator
Copy link
Contributor Author

@Bromeon I don't use custom-godot, should I? I'm just rebuilding 3.4.4 with a newer Emscripten, but it's still 3.4.4

@Bromeon
Copy link
Member

Bromeon commented Jun 26, 2022

@derivator You should only need custom-godot if the generated API JSON would differ from the one shipped in the godot-rust repo. This is usually the case for other Godot minor versions.

I'm not sure if using Emscripten has an effect here. You could run

godot --gdnative-generate-json-api api.json

and diff the generated file against the api.json in the godot-rust repo.

@derivator
Copy link
Contributor Author

godot --gdnative-generate-json-api api.json

I have no idea how I would do that for a wasm build, but I suspect it's fine. It works for me after all 😆

[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
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not needed on nightly Rust:
rust-lang/rust#98149

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
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've updated the guide to reflect the current state of affairs.

I initially had some problems where I still needed -Zbuild-std (to fix missing __cxa_is_pointer_type) and -Zlink-native-libraries=no (to fix wasm-ld: error: unable to find library -lc, but after cargo clean it works without those flags so maybe rust was incorrectly reusing some old build artifact? @hoodmane can you confirm that these flags shouldn't be needed?

Copy link

@hoodmane hoodmane Jul 4, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Currently Pyodide is using:

export RUSTFLAGS= \
	-C link-arg=-sSIDE_MODULE=2 \
	-C link-arg=-sWASM_BIGINT \
	-Z link-native-libraries=no

https://github.com/pyodide/pyodide/blob/main/Makefile.envs#L159

The problem that -Zlink-native-libraries=no fixes is not resolved either on the Rust side or on the Emscripten side. But if it works without it...

Copy link
Member

@Bromeon Bromeon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks to you both for the great writeup already! 😊

src/exporting/html5.md Outdated Show resolved Hide resolved
src/exporting/html5.md Outdated Show resolved Hide resolved
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`.
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

will result in cryptic runtime errors such as indirect call signature mismatch

It might be worth indicating that indirect call signature mismatch does not necessarily mean that there is a version incompatibility: this error message is also the most likely outcome of memory corruption and several other problems.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@derivator any comment on this? 🙂

@Bromeon
Copy link
Member

Bromeon commented Aug 26, 2022

@derivator @hoodmane Any more comments before this is merged? 🙂

@derivator
Copy link
Contributor Author

@Bromeon As far as I can tell at a glance, building Godot shouldn't be necessary anymore with Godot 3.5, as the commit that updates their emscripten version seems to have made it in, but I would still keep that information in the guide, in case the same kind of version mismatch happens in the future. I can try updating the guide this weekend.

@Bromeon
Copy link
Member

Bromeon commented Sep 3, 2022

@derivator have you had a chance to look at it yet? 🙂

@derivator
Copy link
Contributor Author

@Bromeon I'm having a look right now. Some steps will not be necessary anymore, however Emscripten makes no ABI stability promises, so while using the export template provided by godot might work coincidentally, I think it's probably best to always compile it yourself. I will update the guide to reflect this.

Recommend building Godot export template yourself, always
Remove mention of WASM_BIGINT as alternative to panic=abort
@derivator
Copy link
Contributor Author

I have it working with Godot 3.5 following the steps in the guide. I believe -Cpanic=abort shouldn't be necessary anymore thanks to emscripten-core/emscripten#17328, but I'm still getting errors without it.

@Bromeon Bromeon merged commit 2747012 into godot-rust:master Sep 4, 2022
@Bromeon
Copy link
Member

Bromeon commented Sep 4, 2022

Thanks a lot to everyone involved! It's great to finally have a bit more resources on the topic of HTML5 exports ❤️

@GeTechG
Copy link

GeTechG commented Oct 2, 2022

I was able to run on emscripten 3.1.14, Godot 3.5.1, rust nightly 0.65.0 (2022-09-03). I was unable to run as suggested on the latest versions of rust and emscripten, or even 3.1.21 as in the tutorial. A runtime error came out with similar text:

at: init_library (modules/gdnative/nativescript/nativescript.cpp:1479) - Condition "lib_path.length() == 0" is true.

all because I understood different versions of llvm, so I am puzzled how you could run with the latest version of emscripten, as nightly rust builds still have 15.0, not 16.0.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
new-topic A new topic to be added has been requested
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants