What does the linker do?
The linker stitches object files and libraries into a single executable — resolving symbols, assigning final addresses, merging sections, and pulling in library code.
* The linker stitches object files and libraries into one program: resolve symbols, relocate addresses, merge sections, pull in library code. *
Each object file knows its own functions but not where everyone else's live. The linker's job is to make all those references point to real addresses.
Its responsibilities:
- Symbol resolution — match each call (e.g. to
printf) to its definition - Relocation — replace relative placeholders with final memory addresses
- Section merging — combine all the
.text,.data, etc. from every object - Library linking — fold in code from static or shared libraries
gcc main.o utils.o math.o -o program # combine three objects + libs
Static vs. dynamic linking is a key trade-off: static linking copies library code into the executable (bigger file, no runtime dependencies), while dynamic linking loads shared .so/.dll files at run time (smaller file, but the libraries must be present).
Two errors you'll meet constantly: "undefined reference" (a symbol was never defined) and "multiple definition" (a symbol was defined twice).
Go deeper:
Linker (Wikipedia) — symbol resolution, relocation, section merging, static vs dynamic.