The linker maintains three sets as it scans inputs left → right:
E — the set of object files that will end up in the executable.
U — the set of currently undefined symbols.
D — the set of symbols already defined by files in E.
The crucial clause: an archive is searched only against the U that exists when the linker
arrives at it. Symbols that become undefined later (because of an object further right) were
not in U yet, so the archive — already passed — is never revisited.
Consequence (the rule you memorise):
Put objects first, then libraries; and put a library after every object that uses it.
If library A uses library B, write ... A B (the user, then its dependency).
Imagine you're packing a school bag by walking down a hallway of lockers once, never turning
back. Every time you find a note saying "I need a red pen," you grab a red pen from the next
locker that has one. But if you reach a locker full of pens before anyone asked for a pen, you
walk right past it — you only grab what someone has already asked for. So if the kid who needs
the pen is further down the hallway than the pen locker, he never gets his pen. Lesson: put
the askers before the givers.
What direction does the traditional Unix linker scan its command line, and how many times?
Left to right, a single pass (objects/archives processed once; only --start-group or repeating forces re-scan).
What three sets does the linker maintain during resolution?
E (objects going into the executable), U (currently undefined symbols), D (symbols already defined).
When is a member of a static archive .a pulled into the link?
Only if, at the moment the linker reaches the archive, that member defines a symbol currently in U (undefined).
Why does gcc -lm main.o fail while gcc main.o -lm works?
At -lm first, U is empty so sqrt.o isn't pulled; main.o later makes sqrt undefined but libm is already passed. Objects must come before the libraries they use.
General rule for placing libraries on the link line?
Objects first, then libraries; each library after every object/library that depends on it (user before provider).
How do you resolve a circular dependency between two static libraries?
Repeat one library (-lfoo -lbar -lfoo) or wrap them in -Wl,--start-group ... -Wl,--end-group to force repeated scanning.
What does --whole-archive do and why need it?
Forces every member of an archive to be linked, even ones not referenced — needed when a member has side effects (e.g. a constructor) but no referenced symbol.
Strong vs weak symbol rule for multiple definitions?
One strong + several weak → the strong definition is chosen silently; two strong → multiple-definition error. (-fno-common makes tentative globals errors.)
Dekho, jab tum gcc se program banate ho, last mein linker chalta hai jo saare symbols
(functions, global variables) ko unki definition se jodta hai. Yahan ek important baat hai:
purana Unix linker command line ko left se right, sirf ek baar scan karta hai. Woh ek list
rakhta hai "abhi tak kaunse symbols undefined hain" — isko hum U bolte hain. Jab bhi koi
static library (.a) aati hai, linker uske andar sirf woh members uthata hai jo U ke kisi
undefined symbol ko satisfy karte hain. Jo symbol baad mein undefined hoga, uske liye library
dobara nahi dekhi jaati.
Isi wajah se order matters. Agar tum gcc -lm main.o likhoge to fail hoga, kyunki jab -lm
scan hua tab tak main.o padha hi nahi gaya tha, to sqrt undefined hi nahi tha, library khaali
chali gayi. Sahi tareeka hai gcc main.o -lm — pehle object, phir library. Golden rule yaad rakho:
user pehle, provider baad mein. Agar libA libB ko use karti hai to -lA -lB likho.
Do special situations: agar do libraries ek dusre ko call karti hain (circular), to
--start-group ... --end-group use karo, jo linker ko baar-baar scan karne deta hai. Aur agar
kisi library member mein constructor jaisa side-effect hai par koi usko reference nahi karta, to
woh silently chhoot jaayega — wahan --whole-archive lagao. Yeh chhoti baat exam aur real
debugging dono mein "undefined reference" errors ka 80% reason hoti hai, isliye is rule ko pakka
yaad rakho.