I'm having troubles trying to link my shared library(an erlang nif), to another shared library(libpurple), that loads other shared libraries(plugins) using dlopen.
The issue is that mylib.so links to libpurple.so, libpurple.so loads plugins.so using dlopen, and plugins.so can't find symbols from libpurple.so
1> mylib:init().
ok
2> /usr/lib/erlang/erts-6.3/bin/beam.smp: symbol lookup error: /usr/lib/purple-2/libmyspace.so: undefined symbol: purple_account_option_string_new
I'm compiling like:
gcc -fPIC -shared `pkg-config --cflags --libs purple` -I /usr/lib/erlang/erts-6.3/include -o priv/mylib.so c_src/mylib.c
It looks like the problem is with dlopen called on erlang:load_nif, this code has the same problem as the erlang nif, RTLD_NOW | RTLD_GLOBAL fixes it, but i can't change how erlang calls dlopen...
#include <dlfcn.h>
#include <stdio.h>
#include <glib.h>
void (*purple_util_set_user_dir)(const char *dir);
void (*purple_debug_set_enabled)(gboolean enabled);
gboolean (*purple_core_init)(const char *ui);
int main()
{
void* lib = dlopen("/usr/lib/libpurple.so", RTLD_LAZY);
purple_util_set_user_dir = dlsym(lib, "purple_util_set_user_dir");
purple_debug_set_enabled = dlsym(lib, "purple_debug_set_enabled");
purple_core_init = dlsym(lib, "purple_core_init");
purple_util_set_user_dir("/tmp/purpletest");
purple_debug_set_enabled(TRUE);
purple_core_init("test");
return 0;
}
The only workaround that i get to work is calling erlang like LD_PRELOAD=/usr/lib/libpurple.so erl
but is far from ideal.
Looks like the same problem, solved using RTLD_GLOBAL, https://developer.pidgin.im/ticket/7872