Das mit dem "weak-linkage" ist, wie GNU das typische Verhalten
implementiert und erweitert hat.
Wenn der Linker nen Symbol sucht, nimmt er die erste Definition, die er
findet. Dabei wird nicht nur ein Symbol, sondern das gesamte o-File
dazugelinkt, in dem das Symbol gefunden wurde. Definiert ein o-File
mehrere Symbole, kann es zu dem "double-defined"-Fehler kommen[1]. Die
herkömmliche Lösung ist, jedes exportierte Symbol in ein eigenes o-File
zu packen (d.h. ein File für strlen, eins für strcpy, eins für strncpy,
etc).
Mit dem weak/strong Attribut hat GNU das Linken erweitert, indem es
jedem Symbol noch ne Priorität mitgibt. Die Symbole in normalen c-Files
sind strong, die in Libraries typischerweise weak. Kommen dann ein
strong und ein oder mehrere weak-Symbole zusammen, gibt es keine
Fehlermeldung mehr, sondern das strong gewinnt. D.h. aber nicht, dass
nicht beide Versionen im Programm vorhanden sind, es wird halt nur die
strong Version benutzt (neuere Linker können unter bestimmten Umständen
unbenutzte Funktionen wegoptimieren, das ist aber ne weitere
GNU-Extension).
Normalerweise braucht man sich darum nicht zu kümmern - es klappt
einfach. Wenn die double-defined Meldung kommt, stimmt normalerweise in
deinem Programm was nicht und sollte genauer untersucht werden.
[1] Beispiel: strcpy und strncpy sind in einem .o-File im clib. Du
definierst dir dein eigenes strncpy, das explizit mitgelinkt wird (in
z.b. mystrncpy.o). Wenn dein Programm nun strcpy (ohne n) benutzt,
holt der Linker das aus dem clib, leider zusammen mit dem clib-strncpy,
das ja im gleichen File ist. Peng, double defined strncpy.