godot-cpp
godot-cpp copied to clipboard
Can't load GDNative compiled for javascript target
After export game or run it from editor by HTML5 button, I see this error:
index.js:362 ERROR: Can't open dynamic library: bin/javascript64/TinyRTSGDNative.wasm. Error: Could not load dynamic lib: TinyRTSGDNative.wasm index.js:362 Error: TinyRTSGDNative.wasm: file not found, and synchronous loading of external files is not available index.js:362 at: open_dynamic_library (platform/javascript/os_javascript.cpp:1054) - Condition "!p_library_handle" is true. Returned: ERR_CANT_OPEN index.js:362 ERROR: No valid library handle, can't get symbol from GDNative object index.js:362 at: get_symbol (modules/gdnative/gdnative.cpp:510) - No valid library handle, can't get symbol from GDNative object index.js:362 ERROR: No nativescript_init in "res://bin/javascript64/TinyRTSGDNative.wasm" found index.js:362 at: init_library (modules/gdnative/nativescript/nativescript.cpp:1510) - No nativescript_init in "res://bin/javascript64/TinyRTSGDNative.wasm" found
Compiled with latest emscripten and included like windows-version of library which works.
How to load the wasm library? Looks like it is not icluded to exported game.
Can you provide a minimal reproduction project?
There is project: https://drive.google.com/file/d/1aO6qJ2abgQOqiylg_8OFwL2yBP71pTF-/view?usp=sharing
It works on windows but can't find library on html5.
The GDNative libraries in your project are missing the entry point for HTML5:
[gd_resource type="NativeScript" load_steps=2 format=2]
[sub_resource type="GDNativeLibrary" id=1]
entry/Windows.64 = "res://bin/win64/GDNativeLibrary.dll"
dependency/Windows.64 = [ ]
[resource]
resource_name = "AdvancedMath"
class_name = "AdvancedMath"
library = SubResource( 1 )
I.e.,
--- a/GDNAdvancedMath.gdns 2022-05-02 12:40:51.725553633 +0200
+++ b/GDNAdvancedMath.gdns 2022-05-02 12:45:10.138390790 +0200
@@ -1,7 +1,9 @@
[gd_resource type="NativeScript" load_steps=2 format=2]
[sub_resource type="GDNativeLibrary" id=1]
+entry/HTML5.wasm32 = "res://bin/javascript64/TinyRTSGDNative.wasm"
entry/Windows.64 = "res://bin/win64/GDNativeLibrary.dll"
+dependency/HTML5.wasm32 = [ ]
dependency/Windows.64 = [ ]
[resource]
Same for GDNLambertSolver.gdns
(you might want to create a single .gdnlib
and reference it in the .gdns
instead having two embedded sub-resources so it's easier to maintain in the future).
Note: Your binary folder is called javascript64
, I haven't checked the wasm, but just in case, we do not yet support wasm64, so make sure you compile your library as wasm32 (default).
@Faless Oh, I forgot to delete the GDNative folder. It's from other game and not used here.
My gdns is in Scenes/Screens/LogosScreen/LogosScreen.gdns
Yes, I compiled it as 64 bits. I will try the wasm32.
But why the error message tells me that file not found, not the file in wrong format?
Actually, I take the SConstruct file from godot-cpp and I don't see the usage of env["bits"]. Maybe, my emscripten builds for 64 bit by default.
But why the error message tells me that file not found, not the file in wrong format?
The file needs to be included in the .gdns
, otherwise it's not known to Godot and not exported (so your .pck doesn't actually have the file). By default, Godot only exports what the game needs, not all the files in the project folder.
It is included:
[gd_resource type="NativeScript" load_steps=2 format=2]
[sub_resource type="GDNativeLibrary" id=1]
entry/HTML5.wasm32 = "res://bin/javascript64/TinyRTSGDNative.wasm"
entry/Windows.64 = "res://bin/windows64/TinyRTSGDNative.dll"
dependency/HTML5.wasm32 = [ ]
dependency/Windows.64 = [ ]
[resource]
resource_name = "LogosScreen"
class_name = "LogosScreen"
library = SubResource( 1 )
Recompilation of library did not help.
New project: https://drive.google.com/file/d/1v6IvSD60O2rKpSI6IFWs6BUU2ThkoLEZ/view?usp=sharing
There is C++ sources of library https://drive.google.com/file/d/184NpCsJTgKI6le34hHTpdMm-F_Tfa3KY/view?usp=sharing (builds by scons as 'scons platform=javascript target=debug')
I extracted files from the PCK archive and I see that wasm file is inside of it. So, I don't understand why javascript can't see it
Hmmm, I renamed godot_gdnative_init into gdnative_init and godot_nativescript_init into nativescript_init and got the similar error on Windows too:
ERROR: No valid library handle, can't get symbol from GDNative object
at: get_symbol (modules/gdnative/gdnative.cpp:510)
ERROR: No valid library handle, can't terminate GDNative object
at: terminate (modules/gdnative/gdnativ e
cpp:417)
ERROR: Can't resolve symbol godot_gdnative_init, error: 127.
at: (platform/windows/os_windows.cpp:2373)
ERROR: Failed to obtain godot_gdnative_init symbol
at: initialize (modules/gdnative/gdnative.cpp:372)
ERROR: No valid library handle, can't get symbol from GDNative object
at: get_symbol (modules/gdnative/gdnative.cpp:510)
ERROR: No nativescript_init in "res://bin/windows64/TinyRTSGDNative.dll" found
at: init_library (modules/gdnative/nativescript/nativescript.cpp:1510)
ERROR: No valid library handle, can't terminate GDNative object
at: terminate (modules/gdnative/gdnative.cpp:417)
ERROR: Can't resolve symbol godot_gdnative_init, error: 127.
at: (platform/windows/os_windows.cpp:2373)
ERROR: Failed to obtain godot_gdnative_init symbol
at: initialize (modules/gdnative/gdnative.cpp:372)
So, maybe javascript sees the library but name of function is differs? But after renaming the wasm library didn't start work.
@Faless Can I see minimal working project that uses gdnative as wasm library? Is it exist somewhere? I could use it as example to check what did I do wrong.
Sure, it's based on the "test" project from godot-cpp
wasm-example.zip (works with Godot 3.4.4-stable).
Building it with scons is pending in #691 . In the meantim you can build it manually after building the library with:
emcc -s SIDE_MODULE=1 -o bin/wasm/libgdexample.wasm src/init.cpp -L../bin/ -lgodot-cpp.javascript.debug.wasm -I../godot-headers/ -I../include/core -I../include/gen -I../include
I'm wondering if maybe having the gdnative library as a subresource is what breaks it for you.
@Faless Hmmm, it's strange. When I used an external file for library it starts to load the library. But now I got the message: "abort(Assertion failed: undefined). Build with -s ASSERTIONS=1 for more info." Building with assertions=1 does not help.
The example project is working for me, but when I built library by myself and replaced it, I started to receive the same message.
@Faless I just tested on Linux and everything is work with external library resource and compiled on linux.
Maybe, I have a problems in my windows emscripten installation
Linux: $ emcc -v emcc (Emscripten gcc/clang-like replacement + linker emulating GNU ld) 2.0.12 Ubuntu clang version 12.0.0-3ubuntu1~21.04.2 Target: wasm32-unknown-emscripten Thread model: posix InstalledDir: /usr/bin
Windows:
emcc -v emcc (Emscripten gcc/clang-like replacement + linker emulating GNU ld) 3.1.9 (54675bac246e84ca024c182e477665d21fe2e2f7) clang version 15.0.0 (https://github.com/llvm/llvm-project faef447e72a5c63dfb12bb7b02d44c3c916d31cd) Target: wasm32-unknown-emscripten Thread model: posix InstalledDir: F:\workspace\emsdk\upstream\bin
Wow, the versions are very different. I will try to install older version for Windows and try to build again.
Also, it is working on linux if was built using Scons by this Sconstruct file: https://drive.google.com/file/d/1Hp5bGF324kFL-J0k3CKBL3_Jc5U0slWW/view?usp=sharing (you can use it with you test project, just change sources list in file), but not working if was built on windows.
I downgraded the emscriptent to the same version as on linux and now it is working
emcc -v emcc (Emscripten gcc/clang-like replacement + linker emulating GNU ld) 2.0.12 clang version 12.0.0 (Cswircachegitchromium.googlesource.com-external-github.com-llvm-llvm--project 52e240a0721e4120a7143f6f5bab4760d28d48e8) Target: wasm32-unknown-emscripten Thread model: posix InstalledDir: F:/workspace/emsdk/upstream/bin
So, problem was caused by two factors:
- using library resource as subresource instead of gdnlib file
- using the latest emscripten version on the windows