Создание универсального бинарного файла в linux для всех компьютеров x86 - PullRequest
5 голосов
/ 11 февраля 2011

Я пытаюсь скомпилировать двоичный файл проекта с открытым исходным кодом, чтобы нашим пользователям не приходилось самим его компилировать.

Я заметил, что некоторые двоичные файлы созданы на одном 32-битном компьютере с Ubuntu "A«не работает на 32-разрядной машине« B », с сообщениями об ошибках, связанных с отсутствием .so файлов.

Однако, если я скомпилирую с нуля на машине« B », все ошибки исчезнут.

Может ли быть какая-то причина, почему компиляция кода на целевой машине устраняет эти ошибки?Я только запустил "./configure" и "make", но не "make-install", поэтому я не сделал эти файлы .so доступными глобально.

Может быть, компилятор обнаружит, что есть .soфайлы отсутствуют в системной библиотеке и в этом случае связывают статическую библиотеку с исполняемым файлом?

Как Ubuntu компилирует свои пакеты, чтобы пакет i386 работал на всех компьютерах x86?

Ответы [ 4 ]

6 голосов
/ 11 февраля 2011

Я полагаю, что проблема называется "двоичная совместимость" ( тег в переполнении стека посвящен этим проблемам). Когда вы связываете двоичный файл на машине, окружающая среда влияет на двоичный файл, и, будучи запущенным на другом компьютере, он все еще пытается найти среду, аналогичную той, в которой он был скомпилирован.

Допуск к различным средам в этом случае называется двоичной совместимостью .

Как это работает?

Ключевым моментом здесь является то, что даже если вы укажете одинаковые опции для компоновщика на разных машинах, вы все равно можете получить разные двоичные файлы. Например, если вы связываете свой двоичный файл с общей библиотекой с помощью -lfoo, точная версия foo, установленная на компьютере, на котором вы работаете (например, libfoo.so.5), жестко закодирована в двоичный файл. Когда он запускается на компьютере B, он может содержать только libfoo.so.4, и двоичный файл откажется запускаться, потому что ему нужен отсутствующий файл libfoo.so.5. Вот почему перекомпиляция помогает, а без нее не работает.

Пакеты Ubuntu - и пакеты любого другого дистрибутива - все скомпилированы в одной среде (друг с другом). Вот почему они хорошо устанавливаются. А поставщики дистрибутивов следят за тем, чтобы каждая следующая версия была обратно совместима с предыдущими.

Что мне делать?

Если вы хотите, чтобы ваше программное обеспечение было совместимо с различными дистрибутивами, это проще, чем вы думали. Сначала попробуйте скомпилировать ваше приложение на самой старой версии . Поскольку, как я упоминал ранее, современные дистрибутивы обычно обратно совместимы, ваша программа, скорее всего, будет работать на более новых дистрибутивах без проблем.

Чтобы более тщательно проверить полученный пакет и получить дополнительные советы по совместимости, вы можете воспользоваться нашим бесплатным Linux Application Checker . Вы также можете быть заинтересованы в общих советах по упаковке Linux soft .

3 голосов
/ 11 февраля 2011

Если вы скомпилируете код на компьютере, вы, скорее всего, не получите никаких ошибок относительно отсутствующих библиотек, если вы запустите программу на этом компьютере.Во время выполнения настройки все необходимые библиотеки обнаруживаются (это основная причина существования configure, autotools и т. Д.), А соответствующие флаги, такие как -lsomelib и -I / some / include / patch, записываются в make-файл и передаются компилятору и компоновщику..

Если вы копируете этот исполняемый файл на другой компьютер, у которого на компьютере могут быть библиотеки неправильной версии или вообще отсутствуют, поэтому он может не запускаться.

Сценарий конфигурации обычно не создает статическийдвоичные файлы, если вы явно не указали это сделать.

Пакеты Ubuntu не будут работать на всех машинах x86.Но менеджер пакетов выполняет разрешение зависимостей, чтобы убедиться, что в нем отсутствуют неправильные библиотеки или библиотеки, и в противном случае отказывается устанавливать пакет.Если вы форсируете установку независимо от отсутствующих зависимостей, вы можете снова столкнуться с теми же проблемами с отсутствующими библиотеками.

Если вы хотите убедиться, что ваш пакет может работать на любом компьютере, просто свяжите его со статическим.

Если достаточно запустить его в определенном дистрибутиве (например, Ubuntu), вы можете создать пакет самостоятельно.Это требует дополнительных усилий.

2 голосов
/ 11 февраля 2011

Вы можете использовать проект типа Ermine для создания дистрибутивов динамически связанных собственных двоичных файлов с включенными общими библиотеками.

Помимо этого, вы можете компилировать ваш код статически. Для этого потребуется получить исходный код для всего дерева зависимостей, скомпилировать его и ссылаться на эти скомпилированные двоичные файлы при сборке кода. Вы не можете скомпилировать статические двоичные файлы для других общих библиотек (файлы .so). Это может быть настоящей болью, особенно если ваши зависимости имеют свои собственные зависимости.

0 голосов
/ 10 января 2012

Вместо подхода, подверженного ошибкам LD_LIBRARY_PATH (который также требует взаимодействия с пользователем) или статического связывания (не всегда возможно или запрещено GPL), вы можете попытаться использовать относительный путь в качестве пути поиска библиотеки (предлагается в Windows по умолчанию, поскольку ДОС раз). Используйте флаг $ORIGIN с компоновщиком.

Полный подход хорошо описан в этом блоге ( архивная версия ).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...