Подтвердить что ты не робот

Можно ли скомпилировать исходный код C/С++, который выполняется во всех дистрибутивах Linux без перекомпиляции?

Можно ли скомпилировать исходный код C/С++, который выполняется во всех дистрибутивах Linux без перекомпиляции?

Если да, можете ли я использовать любые внешние (нестандартные C/С++) библиотеки?

Я хочу распространять свое двоичное приложение вместо распространения исходного кода.

4b9b3361

Ответ 1

Нет, вы не можете скомпилировать исполняемый файл, который выполняется во всех дистрибутивах Linux. Однако вы можете скомпилировать исполняемый файл, который работает в большинстве дистрибутивов, о которых люди будут заботиться.

  • Скомпилируйте 32-разрядную версию. Скомпилируйте минимальный уровень процессора, который вы готовы поддерживать.

  • Создайте собственную версию glibc. Используйте параметр --enable-kernel для установки минимальной версии ядра, которую вы хотите поддерживать.

  • Скомпилируйте все другие библиотеки, которые вы планируете использовать самостоятельно. Используйте заголовки из вашей сборки glibc и выбранные флаги CPU/compiler.

  • Ссылка статически.

  • Для всего, на что вы не могли ссылаться на статически (например, если вам нужен доступ к разрешению имен по умолчанию для системы или вам нужен PAM), вы должны создать свой собственный вспомогательный процесс и API. Отпустите источник для вспомогательного процесса и дайте им возможность (или ваш установщик) скомпилировать его.

  • Проведите тщательное тестирование на всех платформах, которые необходимо поддерживать.

Возможно, вам придется настроить некоторые библиотеки, если они вызывают функции, которые не могут работать с этим механизмом. Это включает dlopen, gethostbyname, iconv_open и т.д. (Эти функции принципиально полагаются на динамическое связывание. См. Шаг 5 выше. Вы получите предупреждение, когда вы соедините их.)

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

Большинство людей, которые делают это, строят с минимальным поддерживаемым процессором, который является Pentium 4, а минимальная версия ядра - 2.6.0.

Ответ 2

Существуют два различия между установками. Архитектура и библиотеки.

  • Наличие одного двоичного файла для разных архитектур напрямую невозможно; была попытка иметь двоичный файл для нескольких арков в одном файле (fatelf), но он не широко используется и вряд ли набирает силу. Поэтому, по крайней мере, вам нужно распространять отдельные двоичные файлы для ia32, amd64, arm,... (большинство, если не все дистрибутивы amd64 имеют ядро, скомпилированное с поддержкой для запуска кода ia32, хотя)

  • Распределения содержат разные версии библиотек. Вы в порядке, пока API не изменится, вы можете связать эту библиотеку. Некоторые библиотеки обеспечивают постоянную обратную совместимость в пределах основного номера (так что приложение GTK2.2 будет нормально работать с GTK2.30 lib, но не обязательно наоборот). Если вы хотите быть уверенным, вам нужно связать статически со всеми используемыми вами библиотеками, кроме самых простых (возможно, только libc6, который является двоично-совместимым через дистрибутивы AFAIK). Это может увеличить размер двоичного файла, и это одна из причин, почему, например, Acrobat Reader является относительно большой загрузкой, хотя само приложение не является специально богатым функциональным способом.

  • Был период перехода для С++ ABI, который изменился между gcc 2.9 и 3 (IIRC), но старый ABI был бы действительно только на древних установках. Это больше не должно быть для вас isse, и если вы станете связывать статично, в любом случае это не имеет значения.

Ответ 3

Обычно нет.

Существует несколько барьеров.

Различные архитектуры

В то время как 32-битная двоичная система будет работать в системе x86_64, она не будет работать наоборот. Кроме того, существует множество систем ARM.

Ядро ABI

Kernel ABI изменяется очень медленно, но он меняется, поэтому вы не можете поддерживать все возможные версии. Обратите внимание, что в некоторых случаях ядро ​​2.2 все еще используется.

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