Instead of compiling the source code for the respective OS (on which it is targeted), you compile once and run everywhere.
For the sake of this question, I would call it VM (for example, both for Java and .NET). So this the execution of programs becomes something like
------------ ---- ----
| Executable | -> | VM | -> | OS |
------------ ---- ----
It perfectly makes sense, the compiler remain generic for the respective VM. However, the implementation of VM may vary depending on the machine it is going to be installed i.e. (*nix, windows, mac) x (32 bit, 64 bit).
My question is, instead of writing VM for respective machines, why isn't the compiler is written for that specific machine? By this, instead of downloading respective VM you download the respective compiler and that compiler will take care of the machine-code+OS for that specific machine. End result, the execution of native code for any machine. Definitely, each source code would need compilation for that specific machine but now a days, the automated systems, scm builds can help us do this thing.
Do my reasons of being confused are right or I am missing some bits of technicalities here?
Edit:
PORTABILITY:
Yes, it is one reason but is portability a big issue in today's automated systems? how often do we have to worry about the fact that we don't have to compile it for other machines? Having a code compiled for native machine would give much better performance. Take Java for instance, you can't do low level programming on Windows and you have to choose JNI.
Take automated systems like TeamCity/Jenkins or others. We could have such an automated system setup where code submitted through version control would result in the executable.