godot-cpp icon indicating copy to clipboard operation
godot-cpp copied to clipboard

Can't load GDNative compiled for javascript target

Open NicholasShatokhin opened this issue 2 years ago • 17 comments

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.

NicholasShatokhin avatar May 01 '22 21:05 NicholasShatokhin

Can you provide a minimal reproduction project?

Faless avatar May 01 '22 22:05 Faless

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.

NicholasShatokhin avatar May 02 '22 09:05 NicholasShatokhin

The GDNative libraries in your project are missing the entry point for HTML5:

missing_wasm_hl

[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 avatar May 02 '22 10:05 Faless

@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?

NicholasShatokhin avatar May 02 '22 11:05 NicholasShatokhin

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.

NicholasShatokhin avatar May 02 '22 11:05 NicholasShatokhin

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.

akien-mga avatar May 02 '22 11:05 akien-mga

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 )

NicholasShatokhin avatar May 02 '22 12:05 NicholasShatokhin

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')

NicholasShatokhin avatar May 02 '22 12:05 NicholasShatokhin

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

NicholasShatokhin avatar May 02 '22 14:05 NicholasShatokhin

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.

NicholasShatokhin avatar May 02 '22 16:05 NicholasShatokhin

@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.

NicholasShatokhin avatar May 03 '22 12:05 NicholasShatokhin

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

Faless avatar May 03 '22 18:05 Faless

I'm wondering if maybe having the gdnative library as a subresource is what breaks it for you.

Faless avatar May 03 '22 18:05 Faless

@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.

NicholasShatokhin avatar May 03 '22 19:05 NicholasShatokhin

@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.

NicholasShatokhin avatar May 03 '22 19:05 NicholasShatokhin

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.

NicholasShatokhin avatar May 03 '22 19:05 NicholasShatokhin

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:

  1. using library resource as subresource instead of gdnlib file
  2. using the latest emscripten version on the windows

NicholasShatokhin avatar May 03 '22 20:05 NicholasShatokhin