Godot version:
3.0.6.stable.official.8314054
OS/device including version:
ArchLinux x64 rolling
Issue description:
Godot doesn't seem to properly load .gdnlib dependency during runtime.
Steps to reproduce:
I have a GDNative library libgaben.so that depends on libsteam_api.so. They're both in the root dir of the project. I'm able to resolve them via ldd which means they're linked properly:
$ LD_LIBRARY_PATH=. ldd libgaben.so
linux-vdso.so.1 (0x00007fff24798000)
libsteam_api.so => ./libsteam_api.so (0x00007f045bef3000)
libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0x00007f045bb6a000)
libm.so.6 => /usr/lib/libm.so.6 (0x00007f045b7d5000)
libgcc_s.so.1 => /usr/lib/libgcc_s.so.1 (0x00007f045b5bd000)
libc.so.6 => /usr/lib/libc.so.6 (0x00007f045b201000)
libdl.so.2 => /usr/lib/libdl.so.2 (0x00007f045affd000)
libpthread.so.0 => /usr/lib/libpthread.so.0 (0x00007f045addf000)
/usr/lib64/ld-linux-x86-64.so.2 (0x00007f045c36d000)
Now, I create a libgaben.gdnlib file:
[entry]
X11.64="res://libgaben.so"
[dependencies]
X11.64=[ "res://libsteam_api.so" ]
[general]
singleton=false
load_once=false
symbol_prefix="godot_"
reloadable=false
Then I create a NativeScript resource and try to instantiate it in my project and get this error:
0:00:00:0444 - Can't open dynamic library: /home/foobar/src/PROJECT_ROOT/libgaben.so. Error: libsteam_api.so: cannot open shared object file: No such file or directory
----------
孝懈锌:袩芯屑懈谢泻邪
袨锌懈褋: Can't open dynamic library: /home/foobar/src/PROJECT_ROOT/libgaben.so. Error: libsteam_api.so: cannot open shared object file: No such file or directory
效邪褋: 0:00:00:0444
C 袩芯屑懈谢泻邪: Method/Function Failed, returning: ERR_CANT_OPEN
C 袛卸械褉械谢芯: drivers/unix/os_unix.cpp:379
C 肖褍薪泻褑褨褟: open_dynamic_library
Looks like Godot doesn't alter LD_LIBRARY_PATH for depencency libraries when loading entry library.
This is confirmed by the fact that the app works if I put my dependency (libsteam_api.so) into /usr/lib dir.
Any ideas?
If you are on linux, try using RPATh instead of LD_LIBRARY_PATH.
LD_LIBRARY_PATH does a link-time lookup but also a fixed-location load-time lookup of the path.
RPATH does a link-time lookup and a dynamic location load-time lookup of the path.
So with RPATH you can load libraries relative to the working directory. This is more a unix-issue than a GDNative issue :P
Using RPATH totally did the trick. Thanks!
For anyone having the same issue: I've added the following line to load my dependencies from lib dir which is located in the same folder as my library:
env.Append(LINKFLAGS=[
'-Wl,-rpath,\'$$ORIGIN\'/lib'
])
It's a placeholder for the location of my library during runtime. It allows me to load my shared library and all its depencencies from any predefined relative location. Relevant SO answer: https://stackoverflow.com/a/38058216/3455614
Works on 64-bit Linux.
@and3rson To elaborate on how to solve this I was having the same issue. I have my .so libraries in addons/git_for_godot/gdnative/linuxbsd in my project. I added this to the SConstruct:
env.Append(LINKFLAGS=[
'-Wl,-rpath,addons/git_for_godot/gdnative/linuxbsd'
])
I ran echo $ORIGIN and it was blank, what is this variable supposed to be set to? I decided to just set the path to be relative, starting with addons/, and this allows ldd to detect the library, and Godot loads it without throwing any errors, but Godot crashes immediately after running, so I'm still missing something.
Most helpful comment
Using
RPATHtotally did the trick. Thanks!For anyone having the same issue: I've added the following line to load my dependencies from
libdir which is located in the same folder as my library:It's a placeholder for the location of my library during runtime. It allows me to load my shared library and all its depencencies from any predefined relative location. Relevant SO answer: https://stackoverflow.com/a/38058216/3455614
Works on 64-bit Linux.