Как связать разные версии одной и той же библиотеки в 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. Даже если он связывается, это приведет к неопределенному поведению во время выполнения.

Другие вопросы по тегам