We have four stages in the compilation process. They are

  • Pre-processor
  • Compiler
  • Assembler
  • Linker

Creating a helloworld.c program:

#include <stdio.h>

int main()
{
    printf("Hello world!!");
    return 0;
}

Pre-processor:

In Pre-processing stage header-file inclusion, macro substitution, comment removal & conditional compilation will be done. The input to the pre-processor is the ".c" file and the output is the ".i" file. Use the below command to get the preprocessor output (.i) from the (.c) file.

You will not find the stdio.h header file in the preprocessor output. Because it is being expanded at this stage.

$ gcc -E helloworld.c > helloworld.i

or

$ cpp helloworld.c > helloworld.i

Compiler:

In the compiler stage, it performs the

  • Lexical analysis.
  • Syntax analysis.
  • Semantic analysis.
  • Intermediate code generation.
  • Code generation.
  • Code optimization.

The compiler design is again a different subject. please refer to the first chapter of this book to know more about the compilation process.

The input to the compiler is ( .i )  file and output is assembly instructions ( .s ) file.

$ gcc -S helloworld.i 

Assembler:

In the assembler stage, the assembly instructions will be processed by an assembler as a result machine code or binary code will be generated. The input to the assembler is ( .s) file and output is ( .o ) file i.e. a relocatable object file.

$ gcc -c helloworld.s

Linker:

In the dynamic linking stage, standard functions such as printf and scanf will be linked to the code by the dynamic linker. There are two types of linking

  • Static linking  (Used to link functions present in static libraries before execution)
  • Dynamic linking (Used to link functions present in dynamic libraries during runtime)

The input to the linker is multiple ( .o ) files and the output is an executable file ( .exe ).

gcc -O file1.o file2.o file3.o ... fileN.o

Output file: a.out

$ gcc -O helloworld.o

Generating all the intermediate files:

Use the below command to generate all the intermediate files i.e. (.i, .s, .o) at the same time.

$ gcc -save-temps helloworld.c