5.3.3Build Systems & Toolchain

Static libraries — .a - .lib, creation and linking

2,172 words10 min readdifficulty · medium2 backlinks

WHY do static libraries exist?

The two competing goals a static library balances:

  • Reuse — write code once, link it everywhere.
  • Selectivity — don't bloat your executable with code you never call.

WHAT exactly is a .a / .lib?


HOW to build one (first principles)

A library is built in three conceptual stages. Let's derive the command sequence.

We need machine code but not a finished program, so we stop the compiler before linking with -c.

gcc -c add.c    -o add.o     # Why -c? compile only, produce relocatable .o
gcc -c sub.c    -o sub.o     # no main() needed; libraries have no entry point

Stage 2 — Archive the .o files into a .a

ar rcs libmath.a add.o sub.o

Decoding each flag (this is why the command looks the way it does):

flag meaning why you want it
r replace/insert members add the .os, overwriting old versions
c create quietly make the archive if it doesn't exist, no warning
s write a symbol index so the linker can find symbols fast (else run ranlib)
gcc main.o -L. -lmath -o app
  • -L. — add the current directory to the library search path.
  • -lmath — look for libmath.a (the lib prefix and .a suffix are added for you).

Figure — Static libraries — .a  -  .lib, creation and linking

HOW linking actually selects code (the deep part)

This is the source of the famous link order rule.


Worked Examples


Common Mistakes (Steel-manned)


Active Recall

Recall What is the minimal 3-stage pipeline to build & use a static lib?
  1. gcc -c *.c → object files. 2. ar rcs libX.a *.o → archive. 3. gcc main.o -L. -lX -o app → link, with library after its user.
Recall Why does deleting the

.a not break the executable? Because static linking copied the needed machine code into the executable at build time; the archive was only a build-time source.

Recall What does the

s in ar rcs give you? A symbol index so the linker can resolve symbols without scanning every member.

Recall (Feynman, explain to a 12-year-old)

Imagine a box of LEGO bricks (.a). Your toy instructions (main.o) say "I need a red 2×4 brick." The builder (linker) opens the box, takes only the red 2×4 you asked for, snaps it onto your toy, and closes the box. Once your toy is built, you can throw the box away — the brick is already glued on. But the builder only grabs bricks you've already asked for, so you must ask before you reach the box, not after.



Flashcards

What file extension is a static library on Unix vs Windows?
lib<name>.a (Unix) and <name>.lib (Windows/MSVC).
What tool creates a .a archive on Unix?
ar (e.g. ar rcs libX.a *.o).
Decode the flags in ar rcs.
r = insert/replace members, c = create quietly, s = write symbol index.
Why must -c be used when compiling library sources?
To stop at relocatable object files (no linking, no main entry point required).
State the Unix link order rule.
A library must appear AFTER the objects/libraries that reference its symbols (single-pass left-to-right resolution).
Why does gcc -lmath main.o fail but gcc main.o -lmath works?
The linker only pulls archive members that satisfy currently-undefined symbols; with the lib first, nothing is undefined yet so nothing is taken.
Does a static .a need to be present at runtime?
No — its code is copied into the executable at link time; it's a build-time dependency only.
What does nm's T vs U mean?
T = symbol defined (in text/code), U = symbol undefined (needed from elsewhere).
What fixes "archive has no index"?
Re-archive with ar rcs or run ranlib libX.a.
What does -lfoo expand to when searching?
A file named libfoo.a (or libfoo.so) in the -L search paths.
How do you handle cyclic dependencies between two static libs in GNU ld?
Wrap them: -Wl,--start-group -lA -lB -Wl,--end-group.

Connections

Concept Map

gcc -c compile only

addresses are placeholders

ar rcs archive

s flag writes

maps symbol to member

-L path plus -lname

copies only used code

resolves relocations

solves

contrast with

bound at run time

.a no longer needed

C source files

Relocatable .o objects

Relocations to fill later

Static library .a / .lib

Symbol index

Linker

Final executable

Reuse plus selectivity

Shared library .so / .dll

Run-time binding

Hinglish (regional understanding)

Intuition Hinglish mein samjho

Static library matlab ek archive file hoti hai (.a Linux pe, .lib Windows pe) jisme aapke compiled object files (.o) ek box me pack hote hain, saath me ek symbol index hota hai jo batata hai kaunsa function kaunse .o me hai. Banane ke liye 3 step yaad rakho — pehle gcc -c se sirf object files banao (yaha link nahi karte, isliye main() ki zaroorat nahi), phir ar rcs libmath.a add.o sub.o se sab ko pack kar do. Bas, library ready.

Sabse important baat linking ki. Jab aap gcc main.o -L. -lmath -o app chalate ho, linker left-to-right chalta hai aur sirf wahi members uthata hai jinki abhi tak zaroorat hai (undefined symbols). Isiliye order matter karta hai — library hamesha us file ke baad aani chahiye jo usko use karti hai. gcc -lmath main.o likhoge to "undefined reference" error aayega, kyunki jab linker library tak pahuncha tab tak add undefined hi nahi tha, isliye usne kuch utha hi nahi.

Yaad rakho: static linking me code executable ke andar copy ho jaata hai. Isliye build ke baad libmath.a delete bhi kar do to bhi ./app chalega — runtime pe library ki zaroorat hi nahi. Yeh dynamic library (.so/.dll) se ulta hai, jisme file runtime pe chahiye hoti hai. Trick word: COAL — Compile, Objects, Archive, Link. Aur "users left, libs right". Bas yeh do cheezein exam aur real coding dono me bachaa lengi.

Go deeper — visual, from zero

Test yourself — Build Systems & Toolchain

Connections