Будет ли исполняемый файл небольшой, чрезвычайно простой программы, такой как показанная ниже, скомпилированной на одном варианте Linux, работать на другом варианте? Или это нужно будет перекомпилировать?
Имеет ли значение архитектура машины в таком случае, как этот?
int main()
{
return (99);
}
glibc
там, или наоборот. Конечно, это не совсем невозможно .gcc -m32 -static
). При этом любой i386 или amd64 Linux сможет запустить исполняемый файл.Ответы:
По-разному. Что-то скомпилированное для IA-32 (32-разрядная версия Intel) может работать на amd64, поскольку Linux на Intel сохраняет обратную совместимость с 32-разрядными приложениями (с установленным подходящим программным обеспечением). Вот ваш
code
скомпилированный в 32-битной системе RedHat 7.3 (около 2002 года, gcc версии 2.96), а затем скопированный двоичный файл в 64-битную систему Centos 7.4 и его запуск (около 2017 года):Древние RedHat 7.3 - Centos 7.4 (по сути RedHat Enterprise Linux 7.4) остаются в том же семействе «дистрибутивов», поэтому, вероятно, будут иметь лучшую переносимость, чем переход от какой-то случайной установки «Linux с нуля» с 2002 года к другому случайному дистрибутиву Linux в 2018 году ,
То, что скомпилировано для amd64, не будет работать только на 32-битных выпусках Linux (старое оборудование не знает о новом оборудовании). Это также относится к новому программному обеспечению, скомпилированному на современных системах, предназначенных для запуска на древних старых объектах, поскольку библиотеки и даже системные вызовы могут не иметь обратной переносимости, поэтому могут потребоваться приемы компиляции, или получить старый компилятор и т. Д., Или, возможно, вместо этого компиляция по старой системе. (Это хорошая причина, чтобы хранить виртуальные машины древних старых вещей вокруг.)
Архитектура имеет значение; amd64 (или IA-32) сильно отличается от ARM или MIPS, поэтому двоичный файл одного из них не должен работать на другом. На сборку нивелировать
main
часть вашего кода на IA-32 компиляций с помощьюgcc -S code.c
кс которой может справиться система amd64 (в системе Linux - OpenBSD, в отличие от amd64 , не поддерживает 32-разрядные двоичные файлы; обратная совместимость со старыми архивами дает возможность злоумышленникам, например CVE-2014-8866 и друзьям). Между тем в системе MIPS с прямым порядком байтов
main
вместо этого компилируется в:с которым процессор Intel понятия не имеет, что делать, и аналогично для сборки Intel на MIPS.
Вы можете использовать QEMU или другой эмулятор для запуска стороннего кода (возможно, очень, очень медленно).
Тем не мение! Ваш код очень простой, поэтому у него будет меньше проблем с переносимостью, чем с чем-либо еще; программы обычно используют библиотеки, которые со временем менялись (glibc, openssl, ...); для них также может потребоваться установка более старых версий различных библиотек (например, RedHat обычно помещает «compat» где-то в имени пакета)
или, возможно, беспокоиться об изменениях ABI (Application Binary Interface) для старых вещей, которые используют glibc, или о более недавних изменениях из-за C ++ 11 или других выпусков C ++. Можно также скомпилировать static (значительно увеличив бинарный размер на диске), чтобы попытаться избежать проблем с библиотеками, хотя от того, делал ли какой-нибудь старый двоичный файл это, зависит, компилирует ли старый дистрибутив большинство всего динамического (RedHat: да) или нет. С другой стороны, такие вещи
patchelf
могут перенастраивать динамические (ELF, но, вероятно, неa.out
отформатированные) двоичные файлы для использования других библиотек.Тем не мение! Возможность запустить программу - это одно, а на самом деле делать что-то полезное с этим - другое. Старые 32-разрядные двоичные файлы Intel могут иметь проблемы с безопасностью, если они зависят от версии OpenSSL, в которой есть какая-то ужасная проблема безопасности, о которой не сообщалось в бэкпорте, или программа может вообще не иметь возможности вести переговоры с современными веб-серверами (как современные серверы отклоняют старые протоколы и шифры старой программы), или протокол SSH версии 1 больше не поддерживается, или ...
источник
for GNU/Linux 2.6.32
(или такие) в выводеfile /usr/bin/ls
.Короче говоря: если вы переносите скомпилированный двоичный файл с одного хоста на другой, используя ту же (или совместимую) архитектуру , вы, возможно, прекрасно подойдете к другому дистрибутиву . Однако по мере увеличения сложности кода увеличивается вероятность того, что он будет связан с библиотекой, которая не установлена; установлен в другом месте; или установлен на другой версии, увеличивается. Возьмем, к примеру, ваш код, для которого
ldd
сообщается о следующих зависимостях при компиляцииgcc -o exit-test exit-test.c
на хосте Ubuntu Linux (производном от Debian):Очевидно, что этот бинарный файл не запустится, если я перекину его, скажем, на Mac (
./exit-test: cannot execute binary file: Exec format error
). Давайте попробуем переместить его в окно RHEL:О, Боже. Почему это может быть?
Даже для этого варианта использования его не удалось выполнить из-за отсутствия общих библиотек.
Однако, если я скомпилирую его
gcc -static exit-test-static exit-test.c
, портирование на систему без библиотек будет работать нормально. За счет, конечно, дискового пространства:Другим жизнеспособным решением было бы установить необходимые библиотеки на новом хосте.
Как и во многих вещах во вселенной U & L, это кошка с множеством скинов, две из которых описаны выше.
источник
amd64
двоичного файла и запуск его в другомamd64
дистрибутиве или сборкаi386
двоичного файла и запуск в другомi386
дистрибутиве.Добавим к отличным ответам @thrig и @DopeGhoti: Unix или Unix-подобные ОС, включая Linux, традиционно всегда разрабатывались и выстраивались больше для переносимости исходного кода, чем двоичные файлы.
Если у вас нет ничего аппаратного или простой источник, как в вашем примере, вы можете переместить его без каких-либо проблем из практически любой версии Linux или архитектуры в исходный код, если на целевых серверах установлены пакеты разработки C , необходимые библиотеки и соответствующие библиотеки разработки установлены.
Поскольку при переносе более продвинутого кода из более старых версий Linux, удаленных во времени, или более специфических программ, таких как модули ядра, для разных версий ядра, вам, возможно, придется адаптировать и модифицировать исходный код для учета устаревших библиотек / API / ABI.
источник
По умолчанию вы почти наверняка столкнетесь с проблемами с внешними библиотеками. В некоторых других ответах более подробно рассматриваются эти проблемы, поэтому я не буду дублировать их работу.
Однако вы можете скомпилировать множество программ - даже нетривиальных - для переносимости между системами Linux. Ключом является инструментарий, называемый Linux Standard Base . LSB предназначен для создания только этих типов портативных приложений. Скомпилируйте приложение для LSB v5.0, и оно будет работать в любой другой среде Linux (той же архитектуры), которая реализует LSB v5.0. Некоторые дистрибутивы Linux совместимы с LSB, а другие включают наборы / библиотеки LSB в виде устанавливаемого пакета. Если вы создаете свое приложение с использованием инструментов LSB (например,
lsbcc
оболочкиgcc
) и ссылаетесь на версию библиотек LSB, вы создадите переносимое приложение.источник
qemu
вами можно даже запускать программы, скомпилированные для другой архитектуры (не с высокой производительностью, но вы можете запускать их)apt-get install
пару пакетов.Может быть.
Вещи, которые имеют тенденцию ломать это включают.
Если вы избегаете использования каких-либо быстро меняющихся библиотек, избегаете изменений в архитектуре и опираетесь на самый старый дистрибутив, на который вы хотите ориентироваться, у вас есть хороший шанс заставить один двоичный файл работать на многих дистрибутивах.
источник
В дополнение к некоторым вещам, упомянутым ранее, произошли некоторые изменения в формате исполняемого файла. В большинстве случаев linux использует ELF, но в более старых версиях использовались a.out или COFF.
Начало wikihole:
https://en.wikipedia.org/wiki/Comparison_of_executable_file_formats
Возможно, есть способ заставить старые версии работать с новыми форматами, но я лично никогда не изучал это.
источник