Мы хотим создать одну общую библиотеку (.so) для всех дистрибутивов, включая старые. Код написан на C++ и использует возможности C++11, поэтому компилятор должен быть не ниже gcc 4.7. Мы заметили, что если мы скомпилируем наш код на машине Linux с установленным gcc 4.7.2 (например, Ubuntu 12.10), то созданный .so будет иметь «версию 1 (GNU/Linux)», в то время как на более старых ОС (например, CentOS 5.6) version — «версия 1 (SYSV)» — и библиотеки с более новой версией GNU/Linux нельзя использовать в более старых ОС.
Поэтому мы попробовали установить gcc 4.7 на машине с CentOS 5.6, скомпилировать наш код с помощью этого компилятора и статически связать с libstdc++ (-static-libstdc++) — в результате получился файл .so, который можно было использовать в каждом найденном нами Linux.
И это отлично работало для 32-битной версии. Однако, когда мы следовали тому же подходу на 64-битной ОС (CentOS), это не удалось с ошибкой, связанной с тем, что существующий libstdc++.a, на который мы пытались ссылаться, был скомпилирован без –fPIC.
Итак, мы попытались скомпилировать исходники gcc 4.7.2 с параметром «—with-pic», но не смогли слинковаться с новым libstdc++.a — ошибка:
/opt/centos/devtoolset-1.1/root/usr/libexec/gcc/x86_64-CentOS-linux/4.7.2/ld: /usr/local/lib/libFoo.so: узел версии не найден для символа _ZNSs7_M_copyEPcPKcm@GLIBCXX_3. 4 /opt/centos/devtoolset-1.1/root/usr/libexec/gcc/x86_64-CentOS-linux/4.7.2/ld: не удалось установить размеры динамических разделов: неверное значение collect2: ошибка: ld вернул 1 статус выхода
Мы погуглили, что компиляция libstdc++ с параметром –fPIC может быть проблематичной, но почему она работает для 32-битной, а не для 64-битной ОС? Есть ли другой предлагаемый способ создать один .so для всех дистрибутивов Linux?
_ZNSs7_M_copyEPcPKcm
в сообщении об ошибкеstd::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_copy(char*, char const*, unsigned long)
. - person Ali   schedule 21.05.2014