Weak dependency on shared library on Linux

Viewed 1943

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.

3 Answers
Related