L'exécutable d'un petit programme extrêmement simple, tel que celui présenté ci-dessous, compilé sur un type de Linux s'exécutera-t-il sur un autre type? Ou aurait-il besoin d'être recompilé?
L'architecture de la machine est-elle importante dans un cas comme celui-ci?
int main()
{
return (99);
}
glibc
là-bas, ou vice versa. Certes, ce n'est pas tout à fait impossible .gcc -m32 -static
). Ce faisant, tout i386 ou amd64 Linux pourra exécuter le fichier exécutable.Réponses:
Ça dépend. Quelque chose compilé pour IA-32 (Intel 32 bits) peut fonctionner sur amd64 car Linux sur Intel conserve la compatibilité descendante avec les applications 32 bits (avec un logiciel approprié installé). Voici votre
code
compilation sur le système 32 bits RedHat 7.3 (circa 2002, version 2.96 gcc), puis le fichier binaire copié sur et exécuté sur un système Centos 7.4 64 bits (circa 2017):Ancient RedHat 7.3 à Centos 7.4 (essentiellement RedHat Enterprise Linux 7.4) reste dans la même famille de "distribution"; sa portabilité sera donc probablement meilleure que celle de passer d'une installation "Linux from scratch" aléatoire de 2002 à une autre distribution Linux aléatoire en 2018 .
Quelque chose compilé pour amd64 ne fonctionnerait pas avec les versions 32 bits de Linux uniquement (l'ancien matériel ne connaît pas le nouveau matériel). Ceci est également vrai pour les nouveaux logiciels compilés sur des systèmes modernes destinés à fonctionner sur des choses anciennes et anciennes, car les bibliothèques et même les appels système peuvent ne pas être portables en arrière, et peuvent donc nécessiter des astuces de compilation, ou l'obtention d'un ancien compilateur, etc. compiler sur l'ancien système. (C’est une bonne raison de conserver les machines virtuelles d’anciennes choses anciennes.)
L'architecture compte; amd64 (ou IA-32) est très différent d'ARM ou de MIPS, de sorte que le binaire de l'un de ceux-ci ne devrait pas s'exécuter sur un autre. Au niveau de l' Assemblée de la
main
section de votre code sur IA-32 par compilesgcc -S code.c
àqu’un système amd64 peut traiter (sur un système Linux - OpenBSD, en revanche, sur amd64 ne prend pas en charge les fichiers binaires 32 bits; la compatibilité avec les anciens systèmes d’archives donne une certaine marge de manoeuvre aux attaquants, par exemple CVE-2014-8866 et ses amis). En attendant, un système MIPS big-endian
main
compile à la place:qui un processeur Intel n'aura aucune idée de quoi faire, et de même pour l'assemblage Intel sur MIPS.
Vous pouvez éventuellement utiliser QEMU ou un autre émulateur pour exécuter du code étranger (peut-être très, très lentement).
Pourtant! Votre code est très simple et aura donc moins de problèmes de portabilité qu'autre chose; les programmes utilisent généralement des bibliothèques qui ont changé au fil du temps (glibc, openssl, ...); pour ceux-là, il se peut que vous deviez également installer des versions plus anciennes de diverses bibliothèques (par exemple, RedHat place typiquement "compat" quelque part dans le nom du paquet)
ou éventuellement vous soucier des modifications ABI (Application Binary Interface) pour les anciennes choses qui utilisent glibc, ou plus récemment des modifications dues à C ++ 11 ou à d'autres versions C ++. On pourrait aussi compiler statique (en augmentant considérablement la taille du binaire sur le disque) pour éviter les problèmes de bibliothèque, bien que le comportement d’un ancien fichier binaire dépende du fait que l’ancienne distribution Linux compilait presque tout ce qui était dynamique (RedHat: oui) ou non. D’autre part, des éléments tels que les
patchelf
binaires dynamiques de régénération (ELF, mais probablement pas dea.out
format) peuvent utiliser d’autres bibliothèques.Pourtant! Pouvoir exécuter un programme est une chose et faire quelque chose d’utile avec elle en est une autre. Les anciens fichiers binaires Intel 32 bits peuvent poser des problèmes de sécurité s’ils dépendent d’une version d’OpenSSL comportant un problème de sécurité horrible et non rétroporté. Sinon, le programme risque de ne pas pouvoir négocier du tout avec les serveurs Web modernes (comme le les serveurs rejettent les anciens protocoles et les chiffrements de l'ancien programme), ou la version 1 du protocole SSH n'est plus prise en charge, ou ...
la source
for GNU/Linux 2.6.32
(ou tel) dans la sortie defile /usr/bin/ls
.En bref: Si vous prenez un fichier binaire compilé d'un hôte à un autre en utilisant la même architecture (ou une architecture compatible) , vous pourrez peut-être parfaitement le faire passer à une autre distribution . Cependant, au fur et à mesure que la complexité du code augmente, la probabilité d'être lié à une bibliothèque non installée; installé dans un autre endroit; ou installé à une version différente, augmente. Prenons par exemple votre code, pour lequel les
ldd
rapports suivants dépendent des dépendances lors de la compilation avecgcc -o exit-test exit-test.c
un hôte Ubuntu Linux (dérivé de Debian):De toute évidence, cette binaire ne fonctionnera pas si je la remplace par un Mac (
./exit-test: cannot execute binary file: Exec format error
). Essayons de le déplacer dans une boîte RHEL:Oh cher. Pourquoi cela pourrait-il être?
Même pour ce cas d'utilisation, le chariot élévateur a échoué en raison de l'absence de bibliothèques partagées.
Cependant, si je le compile avec
gcc -static exit-test-static exit-test.c
, le porter sur le système sans les bibliothèques fonctionne très bien. Bien sûr, au détriment de l'espace disque:Une autre solution viable consisterait à installer les bibliothèques requises sur le nouvel hôte.
Comme beaucoup de choses dans l'univers U & L, il s'agit d'un chat avec plusieurs peaux, dont deux sont décrites ci-dessus.
la source
amd64
fichier binaire et de l'exécuter sur une autreamd64
distribution, ou de créer uni386
fichier binaire et de l'exécuter sur une autrei386
distribution.Ajout aux excellentes réponses @thrig et @DopeGhoti: Les systèmes d’exploitation Unix ou similaires, y compris Linux, étaient traditionnellement toujours conçus et alignés davantage pour la portabilité du code source que pour les fichiers binaires.
Si vous n’avez rien de matériel spécifique ou une source simple, comme dans votre exemple, vous pouvez le déplacer sans problème entre pratiquement toutes les versions de Linux ou d’architecture en tant que code source, à condition que les packages de développement C soient installés sur les serveurs de destination , les bibliothèques nécessaires et les bibliothèques de développement correspondantes installées.
En ce qui concerne le portage de code plus avancé d'anciennes versions de Linux ou de programmes plus spécifiques, tels que des modules de noyau pour différentes versions du noyau, vous devrez peut-être adapter et modifier le code source afin de prendre en compte des bibliothèques / API / ABI obsolètes.
la source
Par défaut , vous rencontrerez presque certainement des problèmes avec les bibliothèques externes. Certaines des réponses apportent plus de détails sur ces problèmes, je ne vais donc pas reproduire leur travail.
Cependant, vous pouvez compiler de nombreux programmes, même non triviaux, pour pouvoir être portables entre des systèmes Linux. La clé est la boîte à outils appelée Linux Standard Base . Le LSB est conçu pour créer uniquement ce type d'applications portables. Compilez une application pour LSB v5.0 et elle fonctionnera sur tout autre environnement Linux (de même architecture) implémentant LSB v5.0. Quelques distributions Linux sont compatibles LSB, et d'autres incluent les boîtes à outils / bibliothèques LSB en tant que paquet installable. Si vous construisez votre application à l'aide des outils LSB (comme l'
lsbcc
encapsuleur pourgcc
) et établissez un lien avec la version des bibliothèques LSB, vous créerez une application portable.la source
qemu
vous, vous pouvez même exécuter des programmes compilés pour différentes architectures (pas très performantes, mais vous pouvez les exécuter)apt-get install
que de quelques paquets.Peut être.
Les choses qui ont tendance à le casser incluent.
Si vous évitez d'utiliser des bibliothèques à changement rapide, évitez les changements d'architecture et utilisez la distribution la plus ancienne que vous souhaitez cibler, vous avez de bonnes chances de faire fonctionner un binaire sur plusieurs distributions.
la source
En plus de certaines des choses mentionnées précédemment, il y a eu quelques changements dans le format de fichier exécutable. La plupart du temps, Linux utilise ELF, mais les anciennes versions utilisaient a.out ou COFF.
Le début d'un wikihole:
https://en.wikipedia.org/wiki/Comparison_of_executable_file_formats
Il pourrait y avoir un moyen d’obtenir des versions plus anciennes pour utiliser des formats plus récents, mais personnellement, je ne me suis jamais penché sur la question.
la source