Я хочу, чтобы мой исполняемый файл «необязательно зависел» от другого общего объекта. Таким образом, он сможет работать без некоторых символов, если DSO отсутствует.
Я могу добиться этого с помощью вызовов dlopen/dlsym
, но мне приходится вручную загружать каждый символ и добавлять для них обертки следующим образом:
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)(...);
}
Это глупый код, и он напрямую зависит от ABI "my _lib.so", это означает, что я должен обновлять его каждый раз, когда обновляется библиотека.
Я ищу способ заставить ld.so
сделать это за меня. Таким образом, идеальным было бы:
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();
}
Но с этим есть два вопроса:
1. Что делать с этими символами на этапе связывания приложений? Если я явно свяжусь с моим _lib.so, приложение будет строго зависеть от него и, следовательно, не сможет запуститься без моего _lib.so. Если нет, ld
будет жаловаться на неопределенные символы.
2. Как заставить dlopen()
сделать все мои символы _lib.so доступными для моего приложения?
Upd :Я понял, что явное связывание с разделяемой библиотекой без пометки DT_NEEDED
поможет. Но я понятия не имею, как заставить ld
сделать это.