Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why do I have to recompile my C program when I move it from OSX to a Ubuntu machine?

Tags:

c

macos

gcc

ubuntu

I built a bunch of simple C programs for school on my Mac (OSX). I had compiled all of the programs and tested them all on my Mac with a Makefile. Everything worked well.

To prep for an assignment tomorrow, I decided to transfer all of these files (compiled and source code) via SSH to the class network (OS is Ubuntu). I wanted to make sure everything worked as expected there.

Once I transferred everything, when I tried to use the Emacs shell to run the compiled programs, I got a Cannot execute binary file error. Then, once I recompiled via my Makefile over SSH on the Ubuntu machine, it worked fine. But why not before?

I know this is obvious to some of you, but I don't know why a compiled C program will run fine on my machine, but then have to be recompiled on a different machine even with the operating systems being different?

Here is an example of my Makefile compile commands:

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

I'm pretty new to C (obviously). This question, Why does my program run on Ubuntu gcc but not OSX gcc?, seems similar but I don't understand the answer.

like image 406
joshmcode Avatar asked May 02 '16 02:05

joshmcode


2 Answers

Like other have mentioned the C code might be compatible but Linux and OSX use different binary formats which are not compatible. Thus you will need to recompile to make your code run on the other platform.

Linux uses a binary format called ELF

OSX uses a binary format called Mach-O

See Is a Linux executable “compatible” with OS X? for a more in depth explanation.

like image 195
Marius Avatar answered Nov 11 '22 03:11

Marius


so to add to Marius's very good explanation:

they actually use the same x86-64 (amd64) calling convention (ABI) so they are compatible on another level, deeper than just C... but they are packaged in different object file formats (as described by Marius).

The other major difference is the linker... so while they both implement std C functions, they are in different libraries so if they are dynamically linked the symbols are in the wrong place.

like image 3
Grady Player Avatar answered Nov 11 '22 04:11

Grady Player