From f6899e190f26de8365a1f477957635d211c88e87 Mon Sep 17 00:00:00 2001 From: Fabio Alessandrelli Date: Thu, 3 Dec 2020 20:57:58 +0100 Subject: [PATCH] Add JavaScript platform support (emcc, wasm). Includes update to `README.md` with instructions on how to build a GDNative library for webassembly. --- README.md | 15 ++++++++++++--- SConstruct | 32 +++++++++++++++++++++++++++++++- 2 files changed, 43 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 9eccee02..cc653092 100644 --- a/README.md +++ b/README.md @@ -275,9 +275,18 @@ Godot headers repository for more information. #### HTML5 -GDNative isn't supported on the HTML5 platform yet. Support is being tracked on -[issue #12243](https://github.com/godotengine/godot/issues/12243) in the main -Godot repository. +GDNative is supported on [specific exports](https://docs.godotengine.org/en/latest/tutorials/export/exporting_for_web.html#export-options) for the HTML5 platform since Godot `3.2.4`. Linking webassembly modules is currently underspecified in the standard, but [emscripten](https://emscripten.org/), which Godot uses to build the HTML5 version, implements its own linking system. + +To build GDNative libraries you wwill need a recent version of [emscripten](https://emscripten.org/). + +```bash +cd SimpleLibrary +emcc -o bin/libtest.wasm -g -O3 -s SIDE_MODULE=1 src/init.cpp godot-cpp/bin/ -Igodot-cpp/include -Igodot-cpp/include/core -Igodot-cpp/include/gen -Igodot-cpp/godot-headers +``` + +You'll need to replace `` with the file that was created in [**Compiling the cpp bindings library**](#compiling-the-cpp-bindings-library). + +This creates the file `libtest.so` in your `SimpleLibrary/bin` directory. ### Creating `.gdnlib` and `.gdns` files diff --git a/SConstruct b/SConstruct index 3d9863cd..cfb2e953 100644 --- a/SConstruct +++ b/SConstruct @@ -86,7 +86,7 @@ opts.Add(EnumVariable( 'platform', 'Target platform', host_platform, - allowed_values=('linux', 'freebsd', 'osx', 'windows', 'android', 'ios'), + allowed_values=('linux', 'freebsd', 'osx', 'windows', 'android', 'ios', 'javascript'), ignorecase=2 )) opts.Add(EnumVariable( @@ -375,6 +375,34 @@ elif env['platform'] == 'android': env.Append(CCFLAGS=['--target=' + arch_info['target'] + env['android_api_level'], '-march=' + arch_info['march'], '-fPIC'])#, '-fPIE', '-fno-addrsig', '-Oz']) env.Append(CCFLAGS=arch_info['ccflags']) +elif env["platform"] == "javascript": + env["ENV"] = os.environ + env["CC"] = "emcc" + env["CXX"] = "em++" + env["AR"] = "emar" + env["RANLIB"] = "emranlib" + env.Append(CPPFLAGS=["-s", "SIDE_MODULE=1"]) + env.Append(LINKFLAGS=["-s", "SIDE_MODULE=1"]) + env["SHOBJSUFFIX"] = ".bc" + env["SHLIBSUFFIX"] = ".wasm" + # Use TempFileMunge since some AR invocations are too long for cmd.exe. + # Use POSIX-style paths, required with TempFileMunge. + env["ARCOM_POSIX"] = env["ARCOM"].replace("$TARGET", "$TARGET.posix").replace("$SOURCES", "$SOURCES.posix") + env["ARCOM"] = "${TEMPFILE(ARCOM_POSIX)}" + + # All intermediate files are just LLVM bitcode. + env["OBJPREFIX"] = "" + env["OBJSUFFIX"] = ".bc" + env["PROGPREFIX"] = "" + # Program() output consists of multiple files, so specify suffixes manually at builder. + env["PROGSUFFIX"] = "" + env["LIBPREFIX"] = "lib" + env["LIBSUFFIX"] = ".bc" + env["LIBPREFIXES"] = ["$LIBPREFIX"] + env["LIBSUFFIXES"] = ["$LIBSUFFIX"] + env.Replace(SHLINKFLAGS='$LINKFLAGS') + env.Replace(SHLINKFLAGS='$LINKFLAGS') + env.Append(CPPPATH=[ '.', env['headers_dir'], @@ -413,6 +441,8 @@ if env['platform'] == 'android': arch_suffix = env['android_arch'] if env['platform'] == 'ios': arch_suffix = env['ios_arch'] +if env['platform'] == 'javascript': + arch_suffix = 'wasm' library = env.StaticLibrary( target='bin/' + 'libgodot-cpp.{}.{}.{}{}'.format(