Compiling and linking are the two phases that transform your C source code into an executable program
are phases:
- main and fundamental
- differents
They cannot be skipped, as each phase solves a different type of problem in the code
compilation phase
Compilation converts human-written code (.c) into intermediate binary code called object code (.o)
At this stage, the compiler knows which external function is going to be used thanks to the .h file, but it doesn’t know where the actual code is to execute it
This option tells GCC to compile, but to stop before the linking phase:
- -c
- Compile Only
- Tells GCC to run the preprocessing, compilation, and assembly phases, but NOT to run the link phase
gcc -c file.c
file.o is the Implicit Output, GCC generates an output file with the same name, but with the extension .o (e.g. file.o)
If you want the resulting object file to be saved with a different name or path, you must combine the -c and -o options
gcc -c file.c -o build/math_constants.o
This .o file is the one you then package with ar rcs to create the static library (.a)
There are 4 types of files:
- .h (interface, has the definitions/signatures/signatures/domain and image of the functions, It’s like a contract that the compiler must fulfill) (Contains the declarations (prototypes) of functions, structures, and constants) (Tells the compiler (GCC) what functions exist, what arguments they expect, and what type of value they return)
- .c (human-readable font c)
- .o (Incomplete binary files, they are not executable, they lack code to become executable)
- executable (complete binary and executable)
- In C, when we talk about “importing” or using code from other modules or libraries, we always include the .h files and not the .c files
It only needs the library contract (the .h file) to know which functions exist and what arguments they expect. It leaves “holes” where external function calls go
The source file (.c) contains the actual implementation or definition of the functions
The compiler reads the .h to check the call syntax
The linker uses the .c binary (the implementation) to fill the hole and create the executable.
linking pase
The link takes the object codes (.o) and the binary libraries (.a or .so) to connect them and create the final executable binary.
- input: Object files (.o), static (.a) and dynamic (.so) libraries
- output: Executable File (the final binary)
- Resolves External References. The linker fills in the gaps left by the compiler, searching for the actual executable code for each external function
- You need the library implementation binary code (the .a or .so file) to connect the code
gcc main.o libutils.a -o program
The linker converts the program into something that the operating system can load and run.
the diagram is:
first in library/librarys
library files (.c) -> compiler (gcc) -> object files (.o) -> single file .a (with ar rcs) (.o files packaged into a single .a file)
second, in the file that use the library
source code (.c) -> (compiler gcc) object code (.o) -> linker (.a file) -> executable
after
./executable
Here is a real example: