I'm having trouble trying to link my shared library (erlang nif) to another shared library (libpurple) that loads other shared libraries (plugins) using dlopen.
The problem is that mylib.so links to libpurple.so, libpurple.so loads plugins.so using dlopen, and plugins.so cannot find characters 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 compile as:
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 caused by erlang: load_nif, this code has the same problem as erlang nif, RTLD_NOW | RTLD_GLOBAL fixes this, but I cannot 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 I get is to call erlang as LD_PRELOAD=/usr/lib/libpurple.so erl , but is far from ideal.
Looks like the same problem that was solved with RTLD_GLOBAL, https://developer.pidgin.im/ticket/7872
source share