gilzoide / godot-lua-pluginscript

Godot PluginScript for the Lua language, currently based on LuaJIT's FFI
https://gilzoide.github.io/godot-lua-pluginscript/topics/README.md.html
MIT License
300 stars 21 forks source link

"undefined symbol: lua_gettop" when attempting to load luasocket #41

Closed jtbx closed 1 year ago

jtbx commented 1 year ago

When I attempt to load luasocket via local socket = require "socket", Godot outputs the following error:

require: Error loading script metadata: error loading module "socket.core" from file "/home/jeremy/Godot/mygame/rocks/lib/lua/5.1/socket/core.so":
    /home/jeremy/Godot/mygame/rocks/lib/lua/5.1/socket/core.so: undefined symbol: lua_gettop
stack traceback:
    [string "res://script.lua"]:3: in main chunk
    in script_load @ "res://script.lua"
  <C++ Source>  ?:-1 @ require()
gilzoide commented 1 year ago

Hi @jtbx, thanks for the report!

Searching for the error message (undefined symbol: lua_gettop), it seems to be a problem that happens when you build a Lua/C module linking to one Lua installation, but run it with another. I assume you installed luasocket using LuaRocks, so it should have been linked to your system's Lua 5.1 library. When running against Lua PluginScript library, which contains all LuaJIT symbols, the linker doesn't find lua_gettop and stuff just breaks.

So, it's possible that none of the C modules installed via LuaRocks will work with Lua PluginScript, although I still have to do some testing around this. Either way, we need to find a way to make Lua/C modules work, because this problem is quite bad in the usability point of view. Possibly distributing LuaJIT directly instead of statically linking it into our own libraries and using LuaRocks' --lua-dir argument to specify custom Lua installation path will work. This will take some time to get studied and fixed.

In the meantime, I'd suggest using Godot's networking facilities instead. There are both high-level and low-level APIs, including TCP/UDP sockets, WebSocket and even WebRTC. Godot is full of useful stuff and you have all of it available to your Lua scripts!

jtbx commented 1 year ago

Alright, then. Thank you very much!

gilzoide commented 1 year ago

No problem, thanks again for the report.

FYI, I'm testing it here, and it seems the shared libraries are not linked to Lua's DLL at all. This means that it relies on symbols like lua_gettop to have been loaded already, something that does not happen by default in Godot: it doesn't import symbols to the global namespace when dlopening libraries.

I've made it work using an environment with LD_PRELOAD=addons/godot-lua-pluginscript/build/linux_x86_64/liblua_pluginscript.so, but this is just unusable in real life projects. We'll have to find some way to import these symbols, maybe using C or LuaJIT + FFI to dlopen the library itself.

I'm reopening this issue while this doesn't get fixed.

gilzoide commented 1 year ago

By the way @jtbx, which platform are you using? I've only tested this in Linux. I don't know if this problem will arise in other platforms like Windows/macOS, so if you have tested on any of them, please let me know.

gilzoide commented 1 year ago

Update: I've tested here, quick and dirty, and indeed, calling dlopen in the pluginscript library passing the RTLD_LAZY | RTLD_GLOBAL flags fixes the import of Lua/C modules. I'll try to make a proper fix sometime in the following weeks, will let you know.

jtbx commented 1 year ago

By the way @jtbx, which platform are you using?

I'm using Linux.

Update: I've tested here, quick and dirty, and indeed, calling dlopen in the pluginscript library passing the RTLD_LAZY | RTLD_GLOBAL flags fixes the import of Lua/C modules. I'll try to make a proper fix sometime in the following weeks, will let you know.

Alright, thank you.

gilzoide commented 1 year ago

Hey @jtbx sorry about the delay. #44 fixes this issue.

I have added automated tests for this. Unfortunately GitHub Actions Windows runners cannot run Godot 3.X because they lack OpenGL support, but I've checked in my machine and Windows doesn't have the problem to begin with, so it should be good to go in all platforms. Android and iOS systems are very much like Linux and macOS, so I guess it will just work as well. The call to dlopen is protected and errors will be catch and printed anyway, so no worries about that.

If you want, you can test the fix using the artifact from the latest GitHub Actions run: https://github.com/gilzoide/godot-lua-pluginscript/actions/runs/4235923810

Cheers!

jtbx commented 1 year ago

Just tested and it works great! Thanks a lot!

gilzoide commented 1 year ago

FYI I just released version 0.5.2 with this fix and submitted the update to the Asset Library. Had totally forgotten about it =P