1. The preprocessor

Rami Louhibi
3 min readFeb 3, 2021

--

The preprocessor has several roles:

  • it gets rid of all the comments in the source file(s)
  • it includes the code of the header file(s), which is a file with extension .h which contains C function declarations and macro definitions
  • it replaces all of the macros (fragments of code which have been given a name) by their values

The output of this step will be stored in a file with a “.i” extension, so here it will be in main.i.

In order to stop the compilation right after this step, we can use the option “-E” with the gcc command on the source file, and press enter.

2. The compiler

The compiler will take the preprocessed file and generate IR code (Intermediate Representation), so this will produce a “.s” file. That being said, other compilers might produce assembly code at this step of compilation.

We can stop after this step with the “-S” option on the gcc command, and press enter.

3. The assembler

The assembler takes the IR code and transforms it into object code, that is code in machine language (i.e. binary). This will produce a file ending in “.o”.

We can stop the compilation process after this step by using the option “-c” with the gcc command, and pressing enter.

4. The linker

The linker creates the final executable, in binary, and can play two roles:

  • linking all the source files together, that is all the other object codes in the project. For example, if I want to compile main.c with another file called secondary.c and make them into one single program, this is the step where the object code of secondary.c (that is secondary.o) will be linked to the main.c object code (main.o).
  • linking function calls with their definitions. The linker knows where to look for the function definitions in the static libraries or dynamic libraries. Static libraries are “the result of the linker making copy of all used library functions to the executable file”, according to geeksforgeeks.org, and dynamic libraries “don’t require the code to be copied, it is done by just placing the name of the library in the binary file”. Note that gcc uses by default dynamic libraries. In our example this is when the linker will find the definition of our “puts” function, and link it.

By default, after this fourth and last step, that is when you type the whole “gcc main.c” command without any options, the compiler will create an executable program called a.out, that we can run by typing “./a.out” in the command line.

We can also choose to create an executable program with the name we want, by adding the “-o” option to the gcc command, placed after the name of the file or files we are compiling, and pressing enter:

--

--

Rami Louhibi
Rami Louhibi

No responses yet