Компиляция одной общей библиотеки в Linux для всех дистрибутивов

Мы хотим создать одну общую библиотеку (.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?


person user3659253    schedule 21.05.2014    source источник
comment
Как это вообще сработает?   -  person mjs    schedule 21.05.2014
comment
+1 Хорошо изученный вопрос! Ошибка, вероятно, не по вашей вине: я погуглил, не смог установить размеры динамических разделов: неверное значение, и я видел только сообщения об ошибках. Кстати _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


Ответы (2)


Я ответил на это в https://gcc.gnu.org/ml/libstdc++/2014-05/msg00107.html

Это выглядит как https://gcc.gnu.org/bugzilla/show_bug.cgi?id=54482, возможно, это исправлено в GCC 4.7.3 (но я не уверен)

...

PIC реализован по-разному для x86 и x86_64, потому что 64-битный режим имеет встроенную поддержку.

person Jonathan Wakely    schedule 02.06.2014
comment
Я столкнулся с этой же проблемой и могу подтвердить, что обновление до 4.7.3 (с 4.6.3) решило проблему для меня. Связанный вопрос: stackoverflow.com/questions/28593592/ - person Edward; 20.02.2015

Статическое связывание с libc/libstdc++ не должно выполняться, даже если оно работает! Это довольно опасно, потому что многие аспекты безопасности требуют обновлений libc. При статической привязке ни одно обновление не может заполнить дыру.

Я не могу поверить, что существует «универсальная» libc, которая работает на всех платформах Linux. libc — это интерфейс к установленной системе, которая представляет собой большой набор различий. Как одна библиотека подходит всем?

Во время ссылки вы можете попробовать

-static-libstdc++ -static-libgcc

как варианты лд. Может быть, это поможет. Но я бы никогда так не поступил!

person Klaus    schedule 21.05.2014
comment
-1 Он не пытается линковать libc статически. Пожалуйста, перечитайте вопрос. - person Ali; 21.05.2014
comment
Спасибо! Он попытался создать библиотеку, которая работает на нескольких платформах. Поэтому я считаю, что libstdc++ требует libgcc. Извините, что намекнул на это :-) - person Klaus; 21.05.2014
comment
Даже если вы компонуете libstdc++ статически, я не думаю, что статически компоновать libc необходимо. Ваш ответ не отвечает на его вопросы: почему это работает для 32-битной, а не для 64-битной ОС? Есть ли другой предлагаемый способ создать один .so для всех дистрибутивов Linux? Поэтому я не могу отозвать свой отрицательный голос, извините. - person Ali; 21.05.2014