Compilers work by converting code written in a program language such as C or C++ into machine code. Compilers have to target specific processors and specific operating systems to generate code a computer can run.
Different compilers rely on different steps to produce code, but simple compilers for assembly languages are the easiest to create since those languages require programmers to write code that's close to machine code. Slightly higher level languages, such as C, require a bit more work from the compiler but make programming much simpler.
It's important to note that a compiled program only runs on a specific processor or type of processor, although backwards compatibility often provides a compatible target for a broad range of machines. By targeting a 386 processor, for example, developers can write code that works on Intel x86-compatible processors by ignoring more advanced features. Most compilers also target a single operating system; a program compiled for Windows, for example, can't run on Apple or Linux operating systems.
Not all programs rely on compilers. Many of the programming languages that power websites, such as PHP, Python and Ruby, run through interpreters that read the source code and convert it on the fly. This lets programming languages use a higher level of abstraction, which leads to easier coding, but, in most cases, this process sacrifices a significant amount of speed and efficiency.