Как связать разные версии одной и той же библиотеки в g++?
Я пытаюсь выяснить, как загрузить две разные версии libstdC++. Так на машине SLES10. У моего клиента есть процесс Foo, который построен на GCC 4.1.2 и, таким образом, использует версию libstdC++ 6.0.8. Мы также создаем разделяемую библиотеку с именем libBar.so. Эта библиотека будет динамически загружаться Foo во время выполнения. libBar.so компилируется с использованием GCC 4.3.6 и libstdC++ версии 6.0.10.
В настоящее время, когда я пытаюсь заставить Foo загрузить libBar.so, я получаю следующую ошибку.
ошибка: невозможно загрузить общий объект '/usr/lib64/libBar.so': /usr/lib64/libstdc++.so.6: версия `GLIBCXX_3.4.9'не найдена (требуется /usr/lib64/libBar.so)
На данный момент единственный способ заставить это работать - изменить порядок загрузки моей библиотеки (через ld.so.conf) так, чтобы Foo и libbar.so оба загружали одну и ту же (6.0.10) libstdC++. Однако это не решение vialbe, так как оно требует, чтобы я модифицировал систему клиента.
Я хотел бы, чтобы Foo загрузил его версии libstdC++. So и libBar.so со своей собственной версией libstdC++. So, но я не могу понять, как написать свой Makefile, чтобы это произошло. Вот что у меня есть для моей линии LIBADD в Makefile.am...
libBar_la_LIBADD =../../vendor/SLES10/lib/libstdc++.so.6.0.10
Что я хотел бы предположить, что хотел бы эту конкретную версию libstdC++. Так. Однако, когда я запускаю ldd для полностью скомпилированного и связанного libBar.so, это строка, которую я вижу...
libstdC++.so.6 => /usr/lib64/libstdc++.so.6 (0x00002aaaaeac5000)
Почему он не ссылается конкретно на libstdC++. So.6.0.10? Что я должен делать вместо этого?
1 ответ
У меня была похожая проблема со сторонней библиотекой, которая использовала устаревшую версию libstdc++
,
Я решил это, предварительно связав стороннюю библиотеку статически с этой старой версией libstdc++
, Конечным результатом была другая общая библиотека, которая не была нерешенной libstdc++
символы. Командная строка была примерно такой:
ld --relocatable -o lib3rd-party-prelinked.so lib3rd-party.so /usr/lib64/libstdc++.a.6
А потом я использовал lib3rd-party-prelinked.so
вместо lib3rd-party.so
, (Уважать --relocatable
в man ld
).
В моем случае это было возможно, потому что сторонняя библиотека предоставляла C API, в ее интерфейсе не использовались стандартные компоненты библиотеки C++.
Если ваша сторонняя библиотека предоставляет классы стандартной библиотеки C++ в своем интерфейсе, ABI которых отличаются между этими libstdc++
версии, которые не собираются работать. Например, ваша заявка проходит std::list<>
с новым ABI в сторонней библиотеке, которая ожидает std::list<>
со старой версией ABI. Даже если он связывается, это приведет к неопределенному поведению во время выполнения.