Open-Source Internship opportunity by OpenGenus for programmers. Apply now.
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:
- Introduction to GCC
- Compilation
- Example source code
- 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:
- Preprocessing
- Compiling
- Assembling
- 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.