Compiling a C program using GCC

Do not miss this exclusive book on Binary Tree Problems. Get it now for free.

In this article, we have covered how to compile a C program using the GCC compiler along with the different stages such as Preprocessing, compiling, assembling and linking.

Table of contents:

  1. Introduction to GCC
  2. Compilation
  3. Example source code
  4. The compilation process(4 steps)

Introduction to GCC

GCC is an acronym that stands for the GNU Compiler Collection. GCC is a collection of compilers and libraries that offer support for various programming languages such as C, C++, Java, etc.

The GCC compiler is included in most Linux distributions. In this article, we have used Ubuntu for all the examples.
To check if it's already installed in your system, run the command below:

username@hostname:~$ gcc --version

OUTPUT

gcc (Ubuntu 9.3.0-17ubuntu1~20.04) 9.3.0
Copyright (C) 2019 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

Compilation

Compiling a program is the process of transforming the source code(human-readable code) into machine language which is a language that the computer can understand.
A compiler is a computer program that translates the source code written in a high-level programming language(i.e C) to a low-level language such as machine code.

Example Source Code

We have used Vim as our editor.
Create a new file and name it hello.c. The .c file extension indicates that the file contains source code written in C.

username@hostname:~$ vim hello.c

Source code

hello.c
  1 
  2 #include <stdio.h>
  3 
  4 int main() {
  5     printf("Hello World!\n");
  6     return 0;
  7 }
  8 

The compilation process

There are four main steps involved in the compilation process as mentioned below:

  1. Preprocessing
  2. Compiling
  3. Assembling
  4. Linking

We have used a basic hello world program to show how the compiling process takes place.

1. Preprocessor

The preprocessor performs the following tasks:

  • It removes all the comments in the source file and replaces them with a single space.
  • It includes the code from the header files.
  • It replaces the predefined macro names with their expansions.

The GCC compiler has several options available that can stop the compilation after different steps.

To view the output of the pre-processing stage, we can use the command gcc -E program_name.c option as shown below.

username@hostname:~$ gcc -E hello.c

The output of the pre-processor is sent to the terminal. To save the output, run the following command:

username@hostname:~$ gcc -E hello.c > hello.i

The .i file extension indicates that the file is a preprocessed file. The code below is part of the hello.i file.

To view the file run:

username@hostname:~$ vim hello.i

OUTPUT

extern void funlockfile (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__));
# 858 "/usr/include/stdio.h" 3 4
extern int __uflow (FILE *);
extern int __overflow (FILE *, int);
# 873 "/usr/include/stdio.h" 3 4

# 3 "hello.c" 2


# 4 "hello.c"
int main() {
    printf("Hello World");
    return 0;
}

2. Compiler

In this stage, the compiler takes the preprocessed file and depending on the compiler generates IR (Intermediate Representation) code or assembly code.

To stop the compilation process after this step, we can use the command gcc -S program_name.c option as shown below.

username@hostname:~$ gcc -S hello.c

This command creates a hello.s file which contains the assembly code.
To view the file run:

username@hostname:~$ vim hello.s

OUTPUT

        .file   "hello.c"
        .text
        .section        .rodata
.LC0:
        .string "Hello World"
        .text
        .globl  main
        .type   main, @function
main:
.LFB0:
        .cfi_startproc
        endbr64
        pushq   %rbp
        .cfi_def_cfa_offset 16
        .cfi_offset 6, -16
        movq    %rsp, %rbp
        .cfi_def_cfa_register 6
        leaq    .LC0(%rip), %rdi
        movl    $0, %eax
        call    printf@PLT
        movl    $0, %eax
        popq    %rbp
        .cfi_def_cfa 7, 8

3. Assembler

In the third stage, the assembler translates the assembly code into executable machine code.

To stop the compilation process after this step, we can use the command gcc -S program_name.c option as shown below.

username@hostname:~$ gcc -c hello.c

This command creates a hello.o file contains the machine code that is not human readable.

To view the file run:

username@hostname:~$ vim hello.o

OUTPUT

^?ELF^B^A^A^@^@^@^@^@^@^@^@^@^A^@>^@^A^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^X^C^@^@^@^@^@^@^@^@^@^@@^@^@^@^@^@@^@^N^@^M^@ó^O^^úUH<89>åH<8d>=^@^@^@^@¸^@^@^@^@è^@^@^@^@¸^@^@^@^@]ÃHello World^@^@GCC: (Ubuntu 9.3.0-17ubuntu1~20.04) 9.3.0^@^@^D^@^@^@^P^@^@^@^E^@^@^@GNU^@^B^@^@À^D^@^@^@^C^@^@^@^@^@^@^@^T^@^@^@^@^@^@^@^AzR^@^Ax^P^A^[^L^G^H<90>^A^@^@^\^@^@^@^\^@^@^@^@^@^@^@ ^@^@^@^@E^N^P<86>^BC^M^FW^L^G^H^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^A^@^@^@^D^@ñÿ^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^C^@^A^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^C^@^C^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^C^@^D^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^C^@^E^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^C^@^G^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^C^@^H^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^C^@

4. Linker

The tasks performed by the linker include:

  • Linking together all the object files from the different source files.
  • Linking function calls with their definitions. The linker knows the locations of the function definitions in the static or dynamic libraries.

To complete the compilation process, we have two options:

Option 1

Run the following command:

username@hostname:~$ gcc hello.c

When you run this command, the compiler generates an executable program called a.out. To run the executable program type the following command:

username@hostname:~$ ./a.out

Option 2

To give the executable program a different name, we can add the "-o" option to the gcc command after the name of the file we are compiling, as shown below:

username@hostname:~$ gcc hello.c -o helloprogram

To run the executable program, use the command below:

username@hostname:~$ ./helloprogram

With this article at OpenGenus, you must have a strong idea about how to compile a C program using GCC.

Sign up for FREE 3 months of Amazon Music. YOU MUST NOT MISS.