`undefined symbol` error when loading a gdnative plugin

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By 深渊漫步


I was trying to embed a ruby interpreter in my godot project. I modified the SImpleDemo example by adding #include <ruby.h> to the file head and a call ruby_init() to the simple_constructor function body.

But this failed and console gave the error message ERROR: open_dynamic_library: Can't open dynamic library: /home/cichol/godot-ruby/example/bin/libsimple.so. Error: /home/cichol/godot-ruby/example/bin/libsimple.so: undefined symbol: ruby_init.

It seems that libruby was not loaded but I have no idea how to have it loaded. I tried the dependencies field in simple.gdnlib but it doesn’t work either.

The commands I used to compile the shared lib:
gcc -std=c11 -fPIC -c src/simple.c -I/home/cichol/godot_headers/ -I/home/cichol/.rbenv/versions/2.5.1/include/ruby-2.5.0/x86_64-linux -I/home/cichol/.rbenv/versions/2.5.1/include/ruby-2.5.0 -o src/simple.os
gcc -shared -L/home/cichol/.rbenv/versions/2.5.1/lib -lruby -Wall src/simple.os -o bin/libsimple.so

Could you give some tips about this?

Here is a simple reproduction without ruby: GitHub - onyxblade/GDNative-demos at demo .

Even if I create symbolic link libplugin.so in my /usr/local/lib folder and then ldconfig, godot engine still reports undefined symbol: hello.

Is the library in your $PATH environmental variable? That could be one part of the problem.

Ertain | 2018-04-29 18:06

What library should be in the $PATH exactly? I tried adding the path to libruby.so to the $LD_LIBRARY_PATH but it’s still not working.

深渊漫步 | 2018-05-02 02:19

And you tried exporting it? Using the export command? If you have done that, then I’m out of options.

Ertain | 2018-05-02 06:56

I’m afraid so. The GLFWDemo in GDNative-demos repository is similar to my use case however it seems outdated to the latest Godot api and it cannot be successfully run either. I opened an issue for that.

深渊漫步 | 2018-05-02 07:41

Btw, I saw that you used -I/ruby_headers when you built the binary. Interesting place where you put the Ruby headers.

Also, did you try changing around some of the commands in gcc -shared? For instance, adding -wall to that? Or did you try using the -L option in gcc to point to where the custom library is?

Ertain | 2018-05-02 18:22

The -I/ruby_headers is actually -I/home/cichol/.rbenv/versions/2.5.1/include/ruby-2.5.0/x86_64-linux -I/home/cichol/.rbenv/versions/2.5.1/include/ruby-2.5.0. I’m sorry for the confusion. Question edited.

The lib folder is -L/home/cichol/.rbenv/versions/2.5.1/lib. I have made symbolic links for the .so files in /usr/local/lib and ran ldconfig so I think the -L can be omitted. My $LD_LIBRARY_PATH is currently /usr/local/lib /home/cichol/.rbenv/versions/2.5.1/lib.

There is a simple example without godot which uses similar compiling commands working well: https://github.com/CicholGricenchos/issue_reproduction . I will try reproduce this without ruby in godot later.

深渊漫步 | 2018-05-03 03:26

I’ve created a reproduction without ruby: add demo · onyxblade/GDNative-demos@41a63c6 · GitHub . See if it’s easier for you to look into this problem?

深渊漫步 | 2018-05-03 08:51

Drat. I’ve tried covering all the bases, but it doesn’t look like I can help you any further. :frowning: Though why did you include headers and libraries from your own home directory? Why not link with the system ones, i.e. install the Ruby libraries and header files?

Ertain | 2018-05-03 17:27

That’s alright. Those libraries are in home because I use rbenv to manage different ruby versions, which has the default putting everything in home.

深渊漫步 | 2018-05-04 08:06

:bust_in_silhouette: Reply From: 深渊漫步

The link command should be:
gcc -shared src/simple.os -o bin/libsimple.so -L/home/cichol/.rbenv/versions/2.5.1/lib -lruby

The order matters :frowning:

And -Xlinker --unresolved-symbols=ignore-in-shared-libs will be very helpful when linking shared libs.

I have been cursing, gazing, copying, looking up, thinking, scratching my head constantly in the last few days because Godot keeps screaming “CAN’T OPEN DYNAMIC LIBRARY!!!” although all the code I wrote was identically the same to a working example. I couldn’t fathom what I did wrong until I stumbled upon this. It’s been 2-3 frustrating days, and the number could’ve grown up if not for this answer. THANK YOU! I can’t even thank you enough for what you have solved for me.

Rev | 2020-09-16 20:34

How is it done on Windows and macOS? I have the linker working on Linux but not on Windows and macOS.

Aaron Franke | 2021-04-20 02:39