Существуют ли ограничения на использование исполняемых файлов, скомпилированных с помощью g++ в одном дистрибутиве Linux, в другом?

Существуют ли какие-либо особенности или различия между дистрибутивами, которые могут повлиять на двоичные файлы C++, скомпилированные с помощью GCC 4.7.x в одном дистрибутиве, которые используются непосредственно в другом? Я понимаю, что идеальной ситуацией является компиляция из исходного кода на втором дистрибутиве, но я действительно предпочел бы не беспокоиться о компиляции новых версий GCC и исходного кода программы на моей производственной машине. Я относительно неопытный пользователь Linux (отсюда и вопрос!) и по-прежнему предпочитаю IDE, а не компиляцию из командной строки, ssh — это все, что я действительно могу использовать для доступа к производственной машине.

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

Любой совет будет принят с благодарностью!


person Elliott    schedule 19.10.2012    source источник
comment
Ответ во многом зависит от того, связываете ли вы статически или динамически.   -  person PlasmaHH    schedule 19.10.2012
comment
Не должно быть проблем, если только один из них не является 64-разрядным, а другой - 32-разрядным, или если у них установлены значительно разные версии различных общих библиотек. Если вам нужна максимальная переносимость, вы должны сделать его статическим.   -  person Paul Tomblin    schedule 19.10.2012
comment
@PaulTomblin: если вам нужна максимальная переносимость, вы должны скомпилировать из исходного кода.   -  person Martin York    schedule 19.10.2012
comment
Спасибо за комментарии. Статическое/динамическое связывание было определенно проблемой, которую я ожидал увидеть здесь. Правильно ли я понимаю, что версия библиотек для средств ОС, таких как сокеты, привязана к версии ядра? Или они обновляются отдельно? А также являются ли компоненты среды выполнения libgcc и/или libstdС++ единственными вещами, которые я должен учитывать с точки зрения получения двоичного кода, ограниченного ядром С++, работающего на другой установке?   -  person Elliott    schedule 20.10.2012
comment
Могут быть несовместимые версии библиотек (но в этом случае попытка запуска программы будет выдавать ошибку). Более коварными являются изменения в расположении файлов конфигурации и тому подобное.   -  person vonbrand    schedule 20.01.2013
comment
@vonbrand: Спасибо за дополнительную пищу для размышлений!   -  person Elliott    schedule 28.01.2013


Ответы (4)


Если двоичные файлы не созданы на точно той же ОС (включая версию) и точно на том же оборудовании, гарантии отсутствуют.

На практике:

  1. Если аппаратное обеспечение относится к тому же семейству чипов, оно должно работать.

    • This is because most people don't turn on the hardware specific optimizations (but they can).
    • Перемещение двоичных файлов между наборами микросхем вряд ли сработает.
    • Перемещение двоичных файлов со старых на новые члены семейства оборудования, скорее всего, сработает.
    • Перемещение двоичных файлов с более новых на более старые члены аппаратного семейства маловероятно (но это будет зависеть от оптимизации и настроек компилятора (переход с 64-битной на 32-битную архитектуру вряд ли сработает).
  2. Если ОС имеет тот же основной номер, то она должна (вероятно) работать.

    • The version of OS that a binary will work across will depend on the version of the compiler used to build it and the host OS.
    • Если у компилятора есть изменения в генерируемом им ABI, то все ставки сняты. Но обычно изменение в ABI, сгенерированном компилятором, будет серьезной проблемой и, таким образом, произойдет только в основных точках дорожной карты ОС (а не в незначительных приращениях).
  3. Мой совет строить из исходников.

    • Don't specifically go out and update the development environment (use the one that comes with distribution (if you do the default updates they will not break backwards compatibility)).
    • Создать легко, просто прочитайте файл README. Но обычно это включает в себя запуск двух команд ./configure и make. Если вы не хотите ничего особенного, вам обычно не нужно ничего делать.
person Martin York    schedule 19.10.2012
comment
Спасибо за исчерпывающий ответ. Очень признателен! Основная причина, по которой я говорю конкретно о последних версиях GCC, заключается в том, что меня очень интересуют новые возможности C++11. Мне удобно (более или менее) создавать GCC и некоторые зависимости (MPFR и две другие, названия которых я забыл) из исходного кода, но время компиляции/использование ресурсов на производственной машине и беспокойство о поддержке другой установки GCC чувствует себя неловко. Чего я не умею делать (но хочу научиться, когда у меня будет время), так это компилировать свой собственный проект из терминала (хех, я отстой!) или правильно использовать make-файлы. - person Elliott; 20.10.2012
comment
Я действительно предпочел бы сначала попробовать это, а затем подумать о сборке из исходного кода в то время, когда я чувствую себя более комфортно. Сам код — это довольно высокоуровневый материал, наименее переносимая вещь, которую я могу найти, — это одна или две битовые маски. Основываясь на вашем ответе, я пришел к следующему выводу: оба процессора x64 примерно одного и того же семейства поставщиков, работающих под управлением 64-разрядной версии Linux, а дистрибутивы являются последними версиями, поэтому, предположительно, имеют очень похожую версию ядра. И, основываясь на этом, я решил, что это, вероятно, стоит попробовать. Еще раз спасибо за дельный совет! - person Elliott; 20.10.2012
comment
И еще одно, если хотите: какие факторы здесь играют роль? Насколько я понимаю (в широком смысле), это: переносимость сгенерированных инструкций, ABI, версии задействованных библиотек времени выполнения (предположительно тривиальные, если они статически связаны) и версии любых библиотек ОС для таких вещей, как сокеты (которые определяются версией ядра?). Но я вполне могу все еще лаять не на то дерево! :) - person Elliott; 20.10.2012
comment
Текущие версии дистрибутивов (за исключением корпоративных, долгосрочных, которые отстали) включают в себя последние версии GCC (и clang), поэтому вам не нужно компилировать свои собственные. В любом случае сообщается, что поддержка C++-2011 несколько неоднородна. - person vonbrand; 28.01.2013
comment
@Elliott, различия между версиями g++, которые нарушают двоичную совместимость, заключаются в деталях реализации объекта, то есть почти во всем C++-y. - person vonbrand; 28.01.2013

G++ уже давно имеет стабильный ABI, так что это не должно вызывать проблем. Что может вызвать проблемы, так это использование динамически подключаемых библиотек. Система, в которой выполняется программа, должна иметь совместимые версии любых общих библиотек, с которыми был скомпилирован исполняемый файл. Если вы используете только статическую ссылку, у вас не должно возникнуть проблем. Вы можете включить статическое связывание с помощью параметра -static.

person Dirk Holsopple    schedule 19.10.2012
comment
Нет больше правды, к сожалению. В G++ 4.7.0 и 4.7.1 были внесены некоторые изменения в стандартную библиотеку, которые повлияли на ABI, а в версии 4.7.2 были несовместимости с ABI исправлено, что в основном означает, что ни 4.7.0, ни 4.7.1, ни 4.7.2 не совместимы ни с какой предыдущей версией, ни с любой из двух других. - person Damon; 19.10.2012
comment
Спасибо за ответ и спасибо @Damon за информацию, очень полезно! У меня нет сомнений в том, что у меня есть правильные библиотеки времени выполнения и т. Д., Но я не знал, что ищу, пока не прочитал это :) - person Elliott; 20.10.2012

При статической связи должны выполняться два условия:

1) Целевая система и система сборки должны иметь одинаковую архитектуру (с исключениями: вы можете запускать 32-битные двоичные файлы на многих 64-битных хостах)

2) Пакет (g)libc в целевой системе не должен быть старше версии, чем в системе сборки (иногда вы можете избежать незначительных различий в версиях)

С динамической связью все сложнее.

person idefixs    schedule 19.10.2012
comment
Кроме того, если мне больше ничего не нужно, можете ли вы гарантировать, что если я скомпилирую свой код с ключом GCC -march=corei7, он будет работать на всех 64-битных платформах? - person qdii; 19.10.2012
comment
@qdii Судя по всему, здесь нет никаких гарантий, приятель! - person Elliott; 20.10.2012

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

person Tsuneo Yoshioka    schedule 19.10.2012