Pourquoi dois-je recomstackr mon programme C lorsque je le déplace d’OSX sur une machine Ubuntu?

J’ai construit un tas de programmes C simples pour l’école sur mon Mac (OSX). J’ai compilé tous les programmes et les ai tous testés sur mon Mac avec un Makefile. Tout a bien fonctionné.

Pour préparer une mission demain, j’ai décidé de transférer tous ces fichiers (compilés et code source) via SSH vers le réseau de classes (le système d’exploitation est Ubuntu). Je voulais m’assurer que tout fonctionnait comme prévu là-bas.

Une fois que j’ai tout transféré, lorsque j’ai essayé d’utiliser le shell Emacs pour exécuter les programmes compilés, j’ai reçu une erreur Cannot execute binary file . Ensuite, une fois recompilé via mon Makefile via SSH sur la machine Ubuntu, cela fonctionnait bien. Mais pourquoi pas avant?

Je sais que cela est évident pour certains d’entre vous, mais je ne sais pas pourquoi un programme C compilé fonctionnera correctement sur ma machine, mais devra être recompilé sur une autre machine, même si les systèmes d’exploitation sont différents.

Voici un exemple de mes commandes de compilation Makefile:

 example: example.c gcc -Wall -pedantic -ansi example.c -o example 

Je suis assez nouveau pour C (évidemment). Cette question, Pourquoi mon programme s’exécute-t-il sur Ubuntu gcc mais pas sur OSX gcc? , semble similaire mais je ne comprends pas la réponse.

Comme d’autres l’ont mentionné, le code C pourrait être compatible, mais Linux et OSX utilisent des formats binarys différents qui ne sont pas compatibles. Ainsi, vous devrez recomstackr pour que votre code s’exécute sur l’autre plate-forme.

Linux utilise un format binary appelé ELF

OSX utilise un format binary appelé Mach-O

Voir Un exécutable Linux est-il “compatible” avec OS X? pour une explication plus approfondie.

alors pour append à la très bonne explication de Marius:

ils utilisent en fait la même convention d’appel x86-64 (amd64), ils sont donc compatibles à un autre niveau, plus profond que C … mais ils sont emballés dans différents formats de fichiers objects (comme décrit par Marius).

L’autre différence majeure est l’éditeur de liens … alors, bien qu’ils implémentent les deux fonctions std C, ils se trouvent dans des bibliothèques différentes. Par conséquent, s’ils sont liés dynamicment, les symboles sont au mauvais endroit.