What's a compiler? A miserable little pile of secrets! No, actually Dracula, it's a program that takes source code, goes 'NOM NOM NOM', and poops out an executable. Duh.
To be completely accurate, the compiler by itself doesn't output the .exe file. That's done by a separate program called a linker. The compiler processes each .cpp file in your project, turning your C++ statements into machine code that the CPU can understand, and outputs an .obj (object) file that contains machine language instructions for each .cpp file processed. The linker then jams all the objects together and links up the function calls, outputting that sweet, sweet binary executable.
Now compilation of a .cpp file generally proceeds in two phases. The first phase is called 'preprocessing', and we generally say that this is carried out by the 'preprocessor', although in actuality there is no separate program for the preprocessor, it's just a routine run by the compiler. After preprocessing, the compilation proper begins and an .obj file is pooped out. Other files with metadata for debugging purposes etc. may also be pooped out.
The job of the preprocessor is to fuck around with the .cpp file before the compiler proper gets its fingers on it. This is done with macros and preprocessor directives. Preprocessor directives all start with the '#' character. For example, the
#include directive takes another text file and inserts it into the current .cpp file. This is generally used to jam .h files into your .cpp file. Another directive is the
#define direction, which creates a preprocessor macro. The result of running the preprocessor on a .cpp file, with all headers included and all macros expanded is called a translation unit, and this is what is fed into the compiler proper.
The linker has two main jobs: 1) take all the .obj files and jam them into one file (the .exe) and 2) link all the function call addresses to their destinations. You see, when the compiler is translating a function call into machine language, it won't know the address to jump to for the call if its in a different translation unit (.cpp file) because the compiler is only aware of the current translation unit it's working on, so the compiler leaves the addresses blank and the linker then fills them in afterwards.
Besides .obj files, the linker also accepts library (.lib) files as inputs. There's nothing special about .lib files, all they are is a bunch of .obj files jammed together for easy organization.
Visual C++ Compiler
The compiler in Visual Studio is named
cl.exe, and the linker is named
link64.exe for the 64-bit versions). If you're feeling especially masochistic you can try building some code from the command line. Also included is the assembler
ml.exe. Proceed at your own peril ;)