I want to make my executable to be "optionally dependent" on other shared object. Thus it will be able to run without some symbols if DSO is absent.
I can achieve this with dlopen/dlsym calls but I have to manually load each symbol and add wrappers for them like this:
void *my_lib = dlopen("my_lib.so", RTLD_LAZY);
if (!my_lib) {
// ok, I promise not to touch my_lib symbols
} else {
my_foo_ptr = dlsym(my_lib, "my_foo");
my_bar_ptr = dlsym(my_lib, "my_bar");
}
... my_foo(...) {
assert(my_foo_ptr);
return (*my_foo_ptr)(...);
}
... my_bar(...) {
assert(my_foo_ptr);
return (*my_bar_ptr)(...);
}
This is a dumb code and it directly depends on "my_lib.so" ABI, that means that I have to update it each time library updates.
I'm searching for some way to make ld.so do this for me. So the ideal would be:
void *my_lib = dlopen("my_lib.so", /* bring me all my symbols */);
if (!my_lib) {
// ok, I promise not to touch my_lib symbols
} else {
// ok, I can directly call symbols from my_lib.so
my_foo();
my_bar();
}
But there are two questions with this:
1. What to do with these symbols during app linkage phase? If I link to my_lib.so explicitly, the app will be strictly dependent on it and therefore unable to start without my_lib.so. If not, ld will complain about undefined symbols.
2. How to force dlopen() to make all my_lib.so symbols available to my app?
Upd: I realized that explicit linking with shared library without marking it as DT_NEEDED would do the trick. But I have no clue how to make ld do this.