What gcc main.c do on your shell?
It is very important before, to clarify some terms:
1. What GNU Means?
GNU, is a free-software, mass-collaboration project, first announced on September 27, 1983 by Richard Stallman at MIT. Its aim is to give computer users freedom and control in their use of their computers and computing devices, by collaboratively developing and providing software that is based on the following freedom rights: users are free to run the software, share it (copy, distribute), study it and modify it.
2. What is GNU Compiler collection?
Is a compiler system produced by the GNU Project supporting various programming languages. “The GNU Compiler Collection includes front ends for C, C++, Objective-C, Fortran, Ada, Go, and D, as well as libraries for these languages (libstdc++,…). GCC was originally written as the compiler for the GNU operating system. The GNU system was developed to be 100% free software, free in the sense that it respects the user’s freedom.”(/gcc.gnu.org/)
gcc is written in C so the compilation process can be controlled by engineers. If you type man gcc the synopsis is like this:
In this image you can see the variety o process that you source code can be passed. It indicates the stages that the compilation process could have.
3. Source code (.c) file
The source code of a program is specially designed to facilitate the work of computer programmers, who specify the actions to be performed by a computer mostly by writing source code. The source code is often transformed by an assembler or compiler into binary machine code understood by the computer. (Wikipedia)
[~/]$ gcc main.c
This process covers 4 stages in the same order and every single time you execute this command.  Pre-processing,  Compiler,  Assembler and  Linker. So, we are going to see exactly what happen in every stage.
Here is my main.c file
The only way to see this stage is sending the output into a file typing
lets see how the processed_file processed the main.c file just printing the last ten lines with $tail processed_file
As you can see it removes #include <stdio.h>(header) and replaces it with the code from library # 2 “main.c” 2 besides to remove the comments and then, the code is going to pass to another stage.
The output of the Pre-processing stage is passed through the compiler to generate an Assembly code. This code is closer to the machine language. It behave like an instructions specific to the type of processor architecture.
The following is the assembly code for the basic construction of an int main function. Is great how the assembly code is a low-level programming language for a computer to a particular computer architecture which are generally portable across multiple systems.
At that point our computer can not understand nothing, so the function of the assembler process is translate all this code to an object(.o) file that can be understandable by a machine. It means convert the assembly code to a binary code. The output of the assembler is put in a file called main.o . This output becomes the final input into what is called the linker in the compilation process. Note, that the size of the output file will change significantly, the object file is going to weight much more than the .c file.
The last stage is called Linking or linker process. The linker can get the
main.o as input and it also gets any pre-compiled libraries that were imported with the
#include preprocessor directly. The executable file will be an a.out file output.
or just with
An finally… The machine understands us and prints what we asked to print :)
Now you know how a .C file is compiled from start to finish. I hope this explanation would be very useful to understand this really interesting process our machines do every time. If you have any suggestions or comments please feel free to let me know down below. I encourage you to keep being curious and If you want to read more about the process of learning software engineer from zero, I may suggest to follow me!