How does compilation work?
- The preprocessor scans our source code — bringing in any include-files, resolving conditional compilation instructions, adding debug hints (linemarkers), and expanding macros — and outputs expanded C code.
- The compiler translates the expanded C code provided by the preprocessor into lower-level assembly code.
- The assember takes the assembly from the compiler, adds offsets, and produces an object file.
- The linker takes one or more object files or libraries, and combines them to produce a single executable.
.c C source code to be preprocessed
.i C source code not to be preprocessed
.h C header file (not preprocessed or linked)
.s Assembly code
.S Assembly code to be preprocessed
.o Object file
How can we inspect the preprocessor output?
The preprocessor is
cpp. Normally its output is piped directly to the compiler, but we can call cpp directly and save its output:
cpp foo.c > foo.i
gcc -E foo.c > foo.i
How can we inspect the assembler output?
gcc -S foo.c
This generates ‘foo.s’.