Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

understanding the need for compilers for different platforms

I am trying to learn how the whole build chain works so I can better understand what goes on when I do build/link/compile etc.

One point I am having trouble with is this: If the compiler turns the source into native assembly, why can't the same program run on different OSs? Isn't assembly run directly by the CPU? So the same machine code should run on every OS, as long as it is the same architecture, no? Why not?

EDIT: Most of the answers so far are about calling the OS's APIs. That obviously is a problem. My question is about the straight machine code. Does it get passed straight to the CPU or not? If I wrote a program in assembly, would I still need to compile separately for each OS? (side point: If I used standard c++ cin/cout, is that OS dependent, get compiled to direct assembly I/O, or does the answer depend on the compiler?)

like image 211
Baruch Avatar asked Nov 10 '10 07:11

Baruch


2 Answers

Different operating systems support different binary formats (e.g. ELF vs COFF), different dynamic linkers (with *.so, *.dll, and *.dylib files being linked at runtime, after you've distributed your binary), and provide different sets of functions and libraries for using OS-provided functionality.

Different sets of function can be addressed by, for example, the Single UNIX Specification / IEEE Std. 1003.1 (POSIX), which dictates a single set of functions to be provided across all operating systems for various operating system tasks (unfortunately not all OSs -- ahem, Windows -- comply). With regard to binary formats (and also CPU instruction-set architecture), one way to deal with this is to distribute some higher level binary format (bytecode), and then do a just-in-time transformation to the target instruction-set and binary format (although this is more about changing when you do it... it still needs to be done). The low-level virtual machine (LLVM), for example, provides for such a transformation.

like image 155
Michael Aaron Safyan Avatar answered Nov 08 '22 23:11

Michael Aaron Safyan


It comes down to the operating system's API and ABI.

Different operating systems provide different system calls, as well as different mechanisms to invoke those system calls. For example, while POSIX provides fork and execv to create a new process, Windows provides CreateProcess.

Furthermore, there are differences at the assembly level. What assembly code do you use to call a function? Different operating systems expect different calling conventions. Operating systems also do not necessarily agree on the formatting of the executable binary, nor do they agree on other mechanisms such as dynamic linking.

Another point to consider is concurrency and how the OS handles that. Some operating systems recognize threads at the kernel level, while others do not. Some might just prefer using multiple processes, and some might use a completely different model. The APIs are different, and the abstractions might be different. For example, one OS might use locks and semaphores, another might use message passing.

like image 38
Aaron Klotz Avatar answered Nov 08 '22 22:11

Aaron Klotz