Бинарная совместимость между дистрибутивами Linux
Извините, если это очевидный вопрос, но я нашел удивительно мало ссылок в интернете ...
Я работаю с API, написанным на C одним из наших деловых партнеров и предоставленным нам в виде двоичного файла .so, построенного на Fedora 11. Мы тестировали API на машине разработки Fedora 11 без каких-либо проблем. Однако, когда я пытаюсь связать с API на целевой платформе нашего клиента, которая является SuSE Enterprise 10.2, я получаю " формат файла не распознан" ошибка.Команды, которые также являются частью пакета binutils, такие как objdump или nm, дают мне ту же ошибку формата файла. Команда "file" показывает мне:
ELF 64-bit LSB shared object, AMD x86-64, version 1 (SYSV), not stripped
И команда " ldd " показывает:
ldd: warning: you do not have execution permission for `./libuscuavactivity.so.1.1'
./libuscuavactivity.so.1.1: /usr/lib64/libstdc++.so.6: version `GLIBCXX_3.4.9' not found (required by ./libuscuavactivity.so.1.1)
[dependent library list]
Я предполагаю, что это связано с несовместимостью библиотек C на двух платформах, причем проблема заключается в том, что код был скомпилирован против новой версии glibc и т. д. чем тот, который доступен на SuSE 10.2. Я публикую этот вопрос на тот случай, если есть способ компиляции кода на платформе Fedora 11 нашего партнера таким образом, чтобы он также работал на SuSE 10.2.
6 ответов:
Я думаю, что хитрость заключается в том, чтобы построить на вкусе linux с самыми старыми версиями ядра и библиотек C любой из платформ, которые вы хотите поддерживать. В моей работе мы строим на Debian 4, что позволяет нам официально поддерживать Debian 4 и выше, RedHat 3,4,5, SuSE 10 плюс различные другие дистрибутивы (SELinux и т. д.) неофициальным образом.
Я подозреваю, что при создании хорошей новой версии linux становится трудно поддерживать людей на старых машинах.
(edit) я должен упомянуть, что мы используйте компилятор по умолчанию, который поставляется с Debian 4, который, я думаю, является GCC 4.1.2. Установка новых версий компилятора, как правило, значительно ухудшает совместимость.
У Windows есть проблемы с совместимостью между различными realeases, пакетами обновления, установленными SDK и DLL в целом (DLL Hell, кто-нибудь?). Linux не застрахован от подобных проблем.
Проблемы совместимости, которые я видел, включают:
- изменения библиотеки времени выполнения
- изменения библиотеки ссылок
- изменения ядра
- изменения технологии компилятора (например: до и после EGCS версии gcc. Это может быть ваша проблема).
- Проблемы с упаковщиком (RPM vs. APT)
В вашем конкретном случае я бы попросил их сделать "gcc-v" в своей системе и сообщить вам номер версии gcc. Сравните это с тем, что вы используете.
Возможно, вам придется заполучить эту версию компилятора, чтобы построить свою половину.
Вы можете использовать Средство проверки приложений Linux ([1], [2], [3]) для решения проблем совместимости приложения между дистрибутивами Linux. Он будет проверять ваши форматы файлов и все зависимые библиотеки. Он поддерживает почти все популярные дистрибутивы Linux, включая все версии SuSE и Fedora.
Это всего лишь личное мнение, но при распространении чего-либо в двоичной форме на Linux у вас есть несколько вариантов:
Постройте гамму .Дебс И.RPM для каждого дистрибутива под солнцем, с номинальным ".смола.GZ полный двоичных файлов" пакет для всего, что вы пропустили. Первая часть идеальна, но громоздка. Последняя часть приведет вас к пунктам 2 и 3.
Сделайте так, как некоторые предлагают, и найдите самый старый дистрибутив, который вы можете найти и построить там. Моя собственность мнение такое, что это какая-то нелепая идея. См. пункт 3.
Распределите двоичные файлы и статически свяжите , где только сможете. Особенно для libstdc++, который, похоже, является вашей проблемой здесь. По-видимому, существует очень много несовместимых версий libstdc++, что делает его кошмаром совместимости. Если вы не можете связать статически, вы также можете поместить файлы *.so рядом с вашим двоичным файлом и использовать такие вещи, как
LD_PRELOAD
илиLD_LIBRARY_PATH
, чтобы они связывались предпочтительно в во время выполнения. Обратите внимание, что если вы выберете этот маршрут, вам, возможно, придется соблюдать LGPL и т. д. поскольку вы теперь распределяете работу других людей вместе с вашим проектом.Конечно, распространение вашего проекта в исходном виде всегда предпочтительнее в Linux. :- )
Если сообщение не распознано в формате файла, то проблема, скорее всего, одна из упомянутых elmarco в комментарии-а именно, другая архитектура. Это может быть (я не уверен) несоответствие версии динамического компоновщика, но это будет означать, что файл .so был построен с помощью древнего динамического компоновщика. Я не верю, что какая-либо несовместимость в libc может вызвать это-они могут вызвать сбои связи и проблемы во время выполнения (последнее очень редко), но не это.