Как встроить статическую библиотеку в разделяемую библиотеку?

В Linux я пытаюсь создать разделяемую библиотеку libbar.so, в которую встроена коммерческая статическая библиотека (с лицензией все в порядке). Коммерческая библиотека имеет 4 версии: libfoo-seq.a, libfoo-mt.a, libfoo-seq.so и libfoo-mt.so (все они предоставляют одинаковые символы, просто код последовательный/многопоточный, и библиотека статическая/общая). Из этих четырех я хочу, чтобы мой код всегда использовал последовательную библиотеку foo, поэтому, когда я создаю libbar.so, я связываю свои объектные файлы и libfoo-seq.a.

Проблема в том, что пользователи моей библиотеки могли уже получить libfoo-mt.so к тому времени, когда они загружают мой libbar.so, поэтому все символы из libfoo уже присутствуют к моменту считывания libbar.so, поэтому мой вызовы функций в foo разрешаются в многопоточную версию.

Интересно, как я могу решить эту проблему? Какие волшебные флаги мне нужно использовать при компиляции для создания объектных файлов и при связывании объектных файлов с libfoo-seq.a для создания libbar.so?


person LaszloLadanyi    schedule 20.05.2019    source источник


Ответы (1)


Вы можете скрыть символы libfoo в libbar через скрипт версии:

$ cat libbar.map
{
  global: libbar_*;
  local: libfoo_*;
};
$ gcc ... -o libbar.so -Wl,--version-script=libbar.map
person yugr    schedule 20.05.2019
comment
Насколько я понимаю, при этом функции libfoo, встроенные в мой libbar.so, не будут видны снаружи. Но это только одна сторона уравнения. Мне также нужно, чтобы, если функции libfoo уже были загружены при открытии libfoo-mt.so, они не просачивались в libbar.so при его открытии, а libbar.so по-прежнему использовала бы функции из libfoo-seq. а. Будет ли эта часть также верной? - person LaszloLadanyi; 20.05.2019
comment
Да, если символы libfoo скрыты (через приведенный выше скрипт), ваша библиотека больше не будет пытаться импортировать их извне (и, следовательно, они не будут перезаписываться). Вы можете проверить двоичный интерфейс libfoo через readelf -hS --dyn-syms. - person yugr; 20.05.2019
comment
Звучит неплохо, сегодня попробую. А пока... вы случайно не знаете эквивалент этого в Windows и AIX... :-) ? - person LaszloLadanyi; 20.05.2019
comment
В Windows не должно быть этой проблемы (символы там уже скрыты по умолчанию, если вы не пометите их declspec(dllexport)). Нет опыта работы с AIX, но если я правильно прочитал это, он поддерживает сценарии версий как линукс. - person yugr; 20.05.2019
comment
Ваше решение сработало, спасибо. Но я нашел еще более простой вариант для своего случая: просто добавьте --exclude-libs ALL в строку ссылки, что сделает все встроенные статические библиотеки локальными. - person LaszloLadanyi; 21.05.2019