Skip to main content

C++ Linking Overview

How C++ object files are linked into executables. Learn symbol resolution, static vs dynamic linking, and linker optimization.

The Linking Process

Linking combines object files and libraries into a final executable, resolving symbols and fixing addresses.

Linking Process Visualizer

Follow object files through symbol resolution and relocation, then inspect where each external reference is supplied.

Step 1 / 6

Linking Pipeline

  1. 1

    Input Processing

    Read object files and libraries

    Parsing ELF headers and section tables

    Current
  2. 2

    Symbol Collection

    Build global symbol table

    Upcoming
  3. 3

    Symbol Resolution

    Match undefined symbols with definitions

    Upcoming
  4. 4

    Section Merging

    Combine similar sections

    Upcoming
  5. 5

    Relocation

    Fix addresses and offsets

    Upcoming
  6. 6

    Output Generation

    Write executable file

    Upcoming

Input Processing: Parsing ELF headers and section tables.

Input Object Files

Linked Libraries

libm.so

dynamic · 156 KB

Provides: sqrt, log, sin, cos, tan, exp

libc.so

dynamic · 2.1 MB

Provides: printf, sprintf, malloc, free, exit

Linker Command
ld -o program main.o math.o utils.o -lm -lc --dynamic-linker /lib64/ld-linux-x86-64.so.2
Authored ELF teaching model. File sizes and section lists are illustrative; the command demonstrates a low-level linker invocation rather than a complete C++ toolchain link.

What the Linker Does

  1. Symbol Resolution

    • Match undefined symbols with definitions
    • Handle name mangling
    • Resolve weak/strong symbols
  2. Section Merging

    • Combine .text sections (code)
    • Merge .data sections (initialized data)
    • Unite .bss sections (uninitialized data)
  3. Relocation

    • Adjust addresses to final locations
    • Fix function calls and data references
    • Update jump targets
  4. Library Handling

    • Include needed functions from libraries
    • Static: Copy code into executable
    • Dynamic: Create references for runtime

Types of Linking

Static Linking

The linker copies the object code it needs from a static archive into the executable, resolving symbols at link time:

bash
# Create static library
ar rcs libstatic.a file1.o file2.o

# Link statically
g++ main.o libstatic.a -o program

Dynamic Linking

The executable only records the shared libraries it needs; the dynamic linker resolves them at load time:

bash
# Create shared library
g++ -shared -fPIC -o libshared.so file1.o file2.o

# Link dynamically
g++ main.o -L. -lshared -o program
bash
# Basic linking
g++ main.o utils.o -o program

# With libraries
g++ main.o -lm -lpthread -o program

# Specify library path
g++ main.o -L/usr/local/lib -lmylib

# View symbols
nm program

# Check dependencies
ldd program

Check the command-line order

Libraries should come after the objects that use them:

bash
# Wrong (may fail)
g++ -lmylib main.o

# Correct
g++ main.o -lmylib

# Circular dependencies
g++ main.o -lA -lB -lA

Linking Topics

Deep dive into specific aspects:

What's Next?

After linking creates the executable:

If you found this explanation helpful, consider sharing it with others.

Mastodon