16

I am almost sure my problem is due to the fact that the compiled program is compiled as a linux executable, but I just want to double check this.

#include <stdio.h>
#include <stdlib.h>
int main()
{
    printf("Hello world!\n");
    return EXIT_SUCCESS;
}

The above "program" should compile on Windows and Linux just fine, since it is source code compatible, as there are no operating system specific libraries or anything like that.

Yet, when I type in "c99 hello.c -o hello.exe" on my Linux box, and then transfer that "executable" to a windows machine, it refuses to run. From what I understand, Linux generates an executable file that only runs on linux, so adding ".exe" has no effect. To build that program on Linux for Windows, I would need to recompile that program on a Windows machine? Or is there another simpler method that will work?

Thomas E
  • 359
  • 1
  • 4
  • 13
  • 9
    You are understanding (basically) right. The executable on different OSs have different formats (and different models of execution). – Eugene Sh. Aug 20 '15 at 11:56
  • 2
    The other method is named "cross-compilation". – Eugene Sh. Aug 20 '15 at 11:58
  • Linux uses ELF for its binaries. – Alexguitar Aug 20 '15 at 12:02
  • 2
    Answer to the title question: for the same reason a diesel engine won't run with unleaded and vice versa. They are different systems. – Jens Aug 20 '15 at 12:03
  • 2
    in addition to the different file formats (ELF vs. 'Portable Executable' format on Windows), the two operating systems also have different Application Binary Interfaces (ABIs). – Andre Holzner Aug 20 '15 at 12:06
  • This may be a duplicate of my answer here: http://stackoverflow.com/questions/12338811/binary-compatibility-over-what-range-of-machines/12338952#12338952 – Nicholas Wilson Aug 20 '15 at 12:10
  • 1
    "no operating system specific libraries" what's that library for `printf`? Each system uses a different way to print characters out to the console. Moreover not only the binary format is different, the ABI is also different – phuclv Aug 20 '15 at 12:49

2 Answers2

29

Windows and Linux executable files use two different incompatible formats:

On Windows, it is the Portable Executable format.

On Linux it is the ELF (Executable and Linkable Format).

Each format makes uses of the specificities of the OS they are supposed to run on, so they can't normally be executed on another platform.

Also, an executable only contains a small portion of the code that is executed after it is loaded into memory. An executable file is linked to system libraries that provide most of the functionality that allows the program to interact with the system.
As systems are very different from each other, libraries vary, and a program for say, Linux, cannot be run on FreeBSD despite the latter using also ELF, because they are not linked to the same libraries.

To compile a Windows executable on Linux, a technique known as cross-compilation can be used. A compiler is after all just a program that writes into a binary file, so any compiler can in theory write code for any platform, as long as the target system's libraries are available to be linked against.

The MinGW-w64 project provides a toolchain that allows this. For example, you can install it on debian-based systems using the sudo apt-get install mingw-w64 command.

The installed executables can be used like this:

i686-w64-mingw32-gcc hello.c -o hello32.exe      # 32-bit
x86_64-w64-mingw32-gcc hello.c -o hello64.exe    # 64-bit
SirDarius
  • 41,440
  • 8
  • 86
  • 100
  • Notice that this is not all that matters: For instance, both OpenBSD and Linux use ELF for their binaries, yet you cannot execute Linux binaries on OpenBSD. On the other hand, you can execute Windows binaries on Linux with the help of Wine. – fuz Aug 20 '15 at 13:03
  • @FUZxxl good points. I believe there is a compat_linux emulation layer for OpenBSD that allows Linux binaries to run there, though. – SirDarius Aug 20 '15 at 13:07
  • 2
    What I'm trying to hint is that the binary format is a red herring with respect to this question. The real answer is that the operating system the binary tries to interact with is not the same and unless there is some sort of system call translation layer, the binary cannot be run. – fuz Aug 20 '15 at 13:08
0

Its a compilation situation, diferently from java .exe don't have any virtual machine to interpret the code in diferent OS. Then he needs to have all specific .dll's and lib's from OS to execute the job who is made for.

In .exe all things are made to run on a specific OS, other way in Java a virtual machine is the magic who interpret and run your code on diferents OS.