Gcc Driver
this article will explain how gcc driver works, and how you can control its behavior, using command line interface.
to compile any source file from a text to a binary executable, the file goes through many stages, each one is done by a separate program, the gcc job is to orchestrate them and make them work together.
1. Preprocessing
this is the first phase on compiling which meant to resolve all preprocessing statements in the source file like #define
and #include
. to tell gcc that you need only to preprocess the input file w/o compiling or linking you can use the -E
option:
gcc -E main.c -o main.i
main.i file contains the preprocessed version of main.c you can use cpp
command to get same result, cpp stand for C PreProcessing.
2. Compiling
this is the main job of the compiler, where it parses machine independent C file and transformes it into machine depending assembly, this why C is very portable. you can instruct gcc to stop right after this step, by using the -S
option:
gcc -S main.c -o main.s
main.s file contains the assembly instruction, that will later be compiled into a binary.
3. Assembly
this step takes an assembly file as input and gives an object file as an output. to stop gcc after this step, use the option -c
:
gcc -c main.c -o main.o
you can emulate the same thing if you use an actual assembler, for example as
.
4. Linking
the last step is linking, which takes one or many object files, and resolve all there undefined symbols, and assign them addresses, this is where libraries can get involved.
to link a program you don't have to say anything because it is the default:
gcc main.c -o main
./main
there is a separate program called ld
, the same linker used by gcc.
Helpfull Options:
to see gcc in action, use the -v
option and you will see all the commands invoked by the driver. there is also a couple intresting options that allows you to hook into different programs used during compilation steps, to influence there behavior bypassing the driver, e.g you can use -Wp,
to tell the driver to pass an option to the preprocessor:
gcc -Wp,-MMD,$(depfile)
This instruct the preprocessor to generate a dependency map for the compiled src file.
Or you can use -Wa,
to hook into the assembler. Or -Wl,
to pass options to the linker:
gcc -Wl,--entry,func1 main.c
This will instruct the linker to use func1
function as an entry point instead of the default, which is _start
.