У нас есть определенный набор устаревших библиотек C ++, скомпилированных в старой системе выпуска с очень старым компилятором gcc 3.2, использующим libstdc ++. So.5.0.0.Современный CentOS7 будет запускать исполняемый файл, скомпилированный на старой ОС с использованием библиотеки совместимости libstdc ++. So.5.0.7, в то время как текущей версией C ++ с другой библиотекой ABI является libstdc ++. So.6.
Наша новая версия исполняемого файла построена на новой ОС и больше не может быть построена на старой платформе.Но в настоящее время перекомпиляция устаревших библиотек на CentOS7 также не возможна: численные результаты будут немного отличаться.Поэтому я хотел бы использовать их как они с их libstdc ++. So.5, в то время как остальная часть моего бинарного файла использует c ++ версии 6.
этот пост предлагает использовать обёртку c-интерфейсабиблиотека, которая связана со статической версией libstdc ++. a.5.
этот пост в основном предлагает то же самое.
Этот метод представляется возможным в нашем случае, так как интерфейс только в стиле C и не использует объекты C ++.И C-ABI, похоже, работает как своего рода барьер между двумя версиями c ++ lib.
Однако я пока не нашел кого-то, кто предоставил бы статические C ++. 5 библиотеки.Также я думаю, что когда-то слышал разговоры об одновременном использовании двух совместно используемых версий libstdc ++ для lib в одном приложении.Так есть ли решение для сохранения общих библиотек C ++. 5?У меня слабая память, что они также использовали C-библиотеку в качестве границы.Будет ли это также работать с dlopen ()?
Моя текущая ситуация такова:
Скомпилировано на старой ОС со старой версией gcc-3.2, libstdc ++. So.5, 32-битный режим:
- libA1.so, используя C ++
- libA2.so, вызывая libB.so, оба используют C ++, libA2 явно связаны с libstdc ++ с опцией компоновщика -lstdc ++, libB нет, но, вероятно, он получает свои символы из libA
- libwrapper.so, только используя C, а не C ++, связанный с / используя libA1 и libA2.
Скомпилировано на новой ОС с новой версией gcc-4.8.5:
- исполняемый (32-битный) вызов libwrapper.so с помощью системного вызова dlopen (), так что косвенновызов C ++ libs libA1.so и libA2.
- исполняемый файл также использует общий C ++ lib libC.so (но интерфейс в стиле C)
- исполняемый файл также использует общий C ++ lib libB.so (ноинтерфейс в стиле C), который также необходим для libA1 и libA2.
Так что исполняемый файл должен использовать новый libstdc ++. so.6 для libC, но будет косвенно вызывать libA1, libA2, libB, которые должныиспользуйте старую библиотеку libstdc ++. so.5.
Должен ли я ограничивать символы, экспортируемые библиотекой-оберткой, точно в мой API, не выставляя символы c ++, как в комментарии pobedims в 1 ,используя флаг version-script для компоновщика?
Или, может быть, я просто связываю устаревшую библиотеку на старой ОС не с -lstdc ++, а с полным именем /usr/lib/libstdc++.so.5?И libB продолжит получать правильные символы из libA2?
Мои исполняемые ссылки / зависят от ...
- libB.so (C ++)
- libC.так (C ++), который нуждается в libstdc ++. 6
- libwrapper.so (с интерфейсом C), который загружается с использованием динамической загрузки dlopen () и который сам связан с «работниками» libA1 и libA2 (которыетакже представлен интерфейс C):
- libA1.so с использованием C ++. 5
- libA2.so с использованием C ++. 5
- libB.so с использованием C ++. 5
Исполняемый файл связан с -rdynamic, может быть, это проблема?Как я могу быть уверен, что никакие символы в libA1, A2, B не разрешены с использованием символов из исполняемого файла с таким же именем?
Изменить позже / Разрешение : Примечание 1: Попытка соединения на старой платформе с использованием версии архива libstdc ++. A.5 приводит к ошибке, которая исправляется только в более поздней версии gcc> = 3.4:
Ошибка: ld: libwrapper.so: неопределенное имя версионного символа_ZSt10time_put_w @@ GLIBCPP_3.2
ld: не удалось установить размеры динамического сечения: неверное значение
, поэтому это не вариант.
Примечание 2: LibB была проблемой, так как она ожидается рабочими библиотеками и самим исполняемым файлом.Если исполняемый файл использует новую версию libB, он представляет libstdc ++. So.6, символы которого передаются рабочим библиотекам, которые вылетают при запуске.Я изменил версию libB, используемую на ту, которая была скомпилирована в старой системе, просто заменив ее на исполняющую систему.Это возможно из-за того, что простой интерфейс C является двоично-совместимым.Таким образом, мой исполняемый файл (через libB) и рабочие библиотеки libA1 и libA2 используют один и тот же libstdc ++. So.5.Мой (C) исполняемый файл построен напрямую с использованием libstdc ++. So.5.Теперь мой исполняемый файл может быть запущен и работает.
Примечание 3: Я обнаружил некоторые числовые различия между контрольными результатами и новым результатом.Использование механизма LD_PRELOAD помогло решить эти проблемы: LD_PRELOAD = libstdc ++. So.5 my_executable
Кажется, это работает хорошо.Я думаю, что с помощью LD_PRELOAD я убедился, что libstdc ++. So.5 имеет преимущество в предоставлении символов, разрешенных из libstdc ++.То, что я не упомянул ранее: мы использовали компилятор Intel на старой платформе, и я использовал математический lib libimf.so из него следующим образом: LD_PRELOAD = "libimf.so libstdc ++. So.5", чтобы предоставить обе библиотеки.В результате числовые различия исчезли, что, по-видимому, связано с реализацией общих математических функций.