От чего зависит двоичная совместимость разделяемых библиотек в Linux? - PullRequest
0 голосов
/ 13 ноября 2018

Я создаю разделяемую библиотеку в Linux, которая служит «плагином» для некоторого программного обеспечения (точнее, расширяет Mathematica).

Я обнаружил, что если я буду строить на Ubuntu 16.04, то получитсябиблиотека не работает на RHEL 7.6.Тем не менее, если я собираюсь использовать RHEL 7.6, библиотека работает как на RHEL, так и на Ubuntu.

Под словом «не работает» я имею в виду, что Mathematica отказывается загружать его, но дает только общий и бесполезный «сбой».«загрузить» сообщение об ошибке.

Я устранил ряд факторов, которые могут нарушить совместимость, и больше не могу найти. Этот вопрос о том, что еще может повлиять на совместимость, чем то, что я перечислю ниже.

Библиотека написана на смеси C и C ++, но она экспортирует интерфейс C.Он построен с -static-libstdc++ и -static-libgcc.Если я использую ldd для файла .so, то в нем перечислены только следующие зависимости:

linux-vdso.so.1 =>  (0x00007ffc757b9000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fa286e62000)
/lib64/ld-linux-x86-64.so.2 (0x00007fa287854000)

Одним из потенциальных источников несовместимости является версия glibc.Я посмотрел на символы в библиотеке, используя nm -gC, и самая высокая ссылка на версию GLIBC, которую я вижу при сборке на Ubuntu, составляет 2.14.RHEL 7.6 имеет glibc 2.17, т.е. новее, чем 2.14.Таким образом, я не верю, что несовместимость связана с glibc.

Что еще может заставить общий объект, скомпилированный в Ubuntu 16.04, не загружаться в RHEL 7.6?


Обновление: Мне удалось уговорить Mathematica выдать более описательную ошибку (это была не очень хорошо документированная функция), поэтому у меня есть конкретное сообщение об ошибке.То же самое можно увидеть и в предложении @ Ctx установить LD_DEBUG=all.

Ошибка:

IGraphM.so: undefined symbol: _ZTVNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEEE

(IGraphM.so - это моя библиотека.)

Эта функция может показаться частью libstdc ++, если я не ошибаюсь.Почему эта ошибка возникает, если я указал -static-libstdc++ и убедился, что ldd не перечисляет libstdc ++?


Обновление 2:

По рекомендацииSergeyA и это QA , я скомпилировал после определения _GLIBCXX_USE_CXX11_ABI=0. Это исправляет несовместимость.

Но я до сих пор не понимаю, почему.Сообщение об ошибке жалуется на отсутствующий символ.Откуда этот символ обычно загружается?У меня сложилось впечатление, что если я использую -static-libstdc++, то он должен содержаться в моей библиотеке.Это кажется неправильным.

Хотя у меня есть практическое решение проблемы несовместимости для этого конкретного случая, я был бы признателен за некоторые объяснения, поэтому в будущем я смогу решить подобные проблемы самостоятельно.

1 Ответ

0 голосов
/ 13 ноября 2018

Я не могу объяснить, почему ваша библиотека .so не связывает все используемые символы статически (и вместо этого оставляет их как неопределенные), но я могу предложить практическое предложение о том, как решить проблему под рукой.

Вы можете прекратить статически связывать libstdc++ в свой плагин, и вместо этого использовать тот, который доступен для хост-системы.Это не работает для вас из-за несовместимости ABI между платформой сборки и целевой платформой.Вы можете понизить ABI, используемый для вашего плагина, указав макрос _GLIBCXX_USE_CXX11_ABI=0.

...