Free — no signup required

Object Files and the Linking Process

2 min read

From Source to Executable: The Two-Stage Build

Most developers think of compilation as a single step: source code goes in, a binary comes out. In reality, it is two distinct stages, and understanding the boundary between them explains a whole class of build errors.

Stage 1: Compilation → Object Files (.o)

The compiler (cc1, invoked by gcc) translates each source file independently into an object file — produced by stopping the toolchain right after compilation, before any linking happens. An object file is an ELF file, but it is incomplete — it contains machine code with unresolved references. For example, when main.c calls printf, the compiler generates a call instruction but leaves the target address blank, annotated with a note: "fill this in later — it's called printf." Symbol-inspection tools can list these gaps directly: a symbol like printf shows up marked U for "Undefined" — referenced in this object file but not defined here.

Stage 2: Linking → Executable

The linker (ld, invoked by gcc once it's given something to link rather than just compile) takes all object files and libraries, resolves every undefined symbol, assigns final memory addresses, and produces the complete ELF executable. Whether you compile and link multiple source files in one invocation or compile each one separately first, the same linker step runs at the end to stitch everything together.

Why does this matter?

The classic "undefined reference to foo" linker error means the linker searched all provided object files and libraries and never found a definition for foo. This is a linker error, not a compiler error — the distinction tells you where to look. Compiler errors mean your syntax or types are wrong. Linker errors mean you forgot to include a file or library. A common instance of this: calling a math function like sin() compiles cleanly but fails at link time, because the math library isn't linked by default — it has to be requested explicitly.

This is one of 18 chapters

Every chapter is free — Kubernetes, Terraform, SRE, distributed systems, and more — with fast daily review built in.

Sign up free