ar
Unter Linux arist der GNU-Allzweckarchivierer. (Es gibt Nicht-GNU-Varianten arin anderen Unix-ähnlichen Betriebssystemen). Mit der Optionc
ar c... archive-name file...
Es wird ein Archiv mit Kopien von erstellt file.... Das hat archive-namekonventionell aber nicht unbedingt die Erweiterung .a(für Archiv ). Jede file...kann jede Art von Datei sein, nicht unbedingt eine Objektdatei.
Wenn die archivierten Dateien alle Objektdateien sind, ist es normalerweise beabsichtigt, das Archiv zu verwenden, um diese Auswahl von Objektdateien in die Verknüpfung von Programmen oder DSOs (Dynamic Shared Objects) zu übertragen. In diesem Fall archive-namewird üblicherweise auch das Präfix vergeben lib, z. B.
libfoo.adamit es über die Linker-Option als Kandidaten-Linker-Eingabedatei erkannt werden kann -lfoo.
Wird als Linker-Eingabedatei verwendet und libfoo.awird normalerweise als statische Bibliothek bezeichnet . Diese Verwendung ist für unerfahrene Programmierer eine ständige Quelle der Verwirrung, da sie glauben, dass ein Archiv libfoo.amit einem DSO libfoo.so, das normalerweise als dynamische / gemeinsam genutzte Bibliothek bezeichnet wird , vergleichbar ist, und auf dieser Grundlage falsche Erwartungen aufbaut. Tatsächlich sind eine "statische Bibliothek" und eine "dynamische Bibliothek" überhaupt nicht ähnlich und werden bei der Verknüpfung auf völlig unterschiedliche Weise verwendet.
Ein auffälliger Unterschied ist, dass eine statische Bibliothek nicht vom Linker erstellt wird , sondern von ar. Es findet also keine Verknüpfung statt, keine Symbolauflösung. Die archivierten Objektdateien bleiben unverändert: Sie werden einfach in eine Tasche gelegt.
Wenn ein Archiv in die Verknüpfung von etwas eingegeben wird, das vom Linker erstellt wurde, z. B. ein Programm oder ein DSO, prüft der Linker in der Tasche, ob sich darin Objektdateien befinden, die Definitionen für nicht aufgelöste Symbolreferenzen enthalten, die angefallen sind früher in der Verknüpfung. Wenn es welche findet, extrahiert es diese Objektdateien aus der Tasche und verknüpft sie mit der Ausgabedatei, genau so, als ob sie in der Linker-Befehlszeile einzeln benannt worden wären und das Archiv überhaupt nicht erwähnt worden wäre. Die gesamte Rolle eines Archivs bei der Verknüpfung besteht also aus einer Tasche von Objektdateien, aus denen der Linker diejenigen auswählen kann, die er für die Verknüpfung benötigt.
Standardmäßig armacht GNU seine Ausgabearchive für die Verwendung als Linkereingaben bereit. Es fügt dem Archiv eine falsche "Datei" mit einem magischen falschen Dateinamen hinzu und schreibt in diese falsche Datei Inhalte, die der Linker als Nachschlagetabelle aus den globalen Symbolen lesen kann, die von allen Objektdateien im Archiv definiert werden zu den Namen und Positionen dieser Objektdateien im Archiv. Diese Nachschlagetabelle ermöglicht es dem Linker, im Archiv nach Objektdateien zu suchen, die nicht aufgelöste Symbolreferenzen definieren, die er zur Hand hat.
Sie können das Erstellen oder Aktualisieren dieser Nachschlagetabelle mit der Option q(=
quick ) - die Sie tatsächlich in Ihrem eigenen arBeispiel verwendet haben - und auch mit der Option (groß) S(= keine Symboltabelle ) unterdrücken. Und wenn Sie aufrufen ar, um ein Archiv zu erstellen oder zu aktualisieren, das aus irgendeinem Grund keine (aktuelle) Symboltabelle hat, können Sie ihm eine sOption geben.
Ranlib
ranliberstellt überhaupt keine Bibliotheken. Unter Linux ranlibhandelt es sich um ein Legacy-Programm, das einem arArchiv eine (aktuelle) Symboltabelle hinzufügt, wenn es keine hat. Die Wirkung ist genau die gleiche wie ar sbei GNU ar. In der Vergangenheit war der Kludge, der die magische Fälschungsdatei in ein Archiv injizierte , bevor der Linker in der Lage arwar, eine Symboltabelle selbst zu generieren ranlib, damit der Linker Objektdateien daraus auswählen konnte. In Nicht-GNU-Unix-ähnlichen Betriebssystemen wird dies ranlibmöglicherweise noch für diesen Zweck benötigt. Ihr Beispiel:
ar qc libgraphics.a *.o
ranlib libgraphics.a
sagt:
- Erstellen Sie,
libgraphics.aindem Sie alle *.oDateien im aktuellen Verzeichnis ohne Symboltabelle an ein Archiv anhängen .
- Fügen Sie dann eine Symboltabelle hinzu
libgraphics.a
Unter Linux hat dies den gleichen Nettoeffekt wie:
ar cr libgraphics.a *.o
Erstellt selbst ar qc libgraphics.a *.oein Archiv, das der Linker nicht verwenden kann, da er keine Symboltabelle enthält.
ld
Ihr Beispiel:
ld -r -o libgraphics.a *.o
ist eigentlich ziemlich unorthodox. Dies zeigt die ziemlich seltene Verwendung des Linkers ,
ldum eine zusammengeführte Objektdatei zu erstellen, indem mehrere Eingabedateien zu einer einzigen Ausgabeobjektdatei verknüpft werden, bei der die Symbolauflösung angesichts der Eingabedateien so weit wie möglich erfolgt ist . Die -r(= relocatable ) Option weist den Linker eine Zielobjektdatei (eher als ein Programm oder DSO) zu erzeugen , indem die Eingänge so weit wie möglich , die Verknüpfung und nicht das linkaqe zu versagen , wenn undefinierte Symbolreferenzen in der Ausgabedatei verbleiben. Diese Verwendung wird als partielle Verknüpfung bezeichnet .
Die Ausgabedatei von ld -r ... ist eine Objektdatei, nicht ein ar Archiv und eine Ausgabedatei angeben , dass aussieht wie das ein arArchiv nicht es eine macht. Ihr Beispiel zeigt also eine Täuschung. Diese:
ld -r -o graphics.o *.o
wäre wahr. Mir ist nicht klar, was der Zweck einer solchen Täuschung sein könnte, denn selbst wenn eine ELF-Objektdatei aufgerufen libgraphics.awird und entweder mit diesem Namen oder mit einer Verknüpfung in eine Verknüpfung eingegeben -lgraphicswird, identifiziert der Linker sie korrekt als ELF-Objektdatei , kein arArchiv, und verwendet es so, wie es eine Objektdatei in der Befehlszeile verwendet: Es verknüpft es bedingungslos mit der Ausgabedatei, während der Zweck der Eingabe eines echten Archivs darin besteht, Archivmitglieder nur unter der Bedingung zu verknüpfen , dass auf sie verwiesen wird . Vielleicht haben Sie hier nur ein Beispiel für schlecht informierte Links.
Einpacken ...
Wir haben tatsächlich nur einen Weg gesehen, etwas zu erzeugen, das herkömmlicherweise als Bibliothek bezeichnet wird , und das ist die Herstellung einer sogenannten statischen Bibliothek , indem einige Objektdateien archiviert und eine Symboltabelle in das Archiv eingefügt werden.
Und wir haben überhaupt nicht gesehen, wie man die andere und wichtigste Art von Dingen produziert, die üblicherweise als Bibliothek bezeichnet werden , nämlich ein dynamisches gemeinsames Objekt / eine gemeinsam genutzte Bibliothek / eine dynamische Bibliothek.
Wie ein Programm wird vom Linker ein DSO erzeugt . Ein Programm und ein DSO sind Varianten der ELF-Binärdatei, die der OS Loader versteht und zum Zusammenstellen eines laufenden Prozesses verwenden kann. Normalerweise rufen wir den Linker über eine eine der GCC - Frontends ( gcc, g++, gfortran, usw.):
Programm verknüpfen:
gcc -o prog file.o ... -Ldir ... -lfoo ...
Verknüpfen eines DSO:
gcc -shared -o libbar.so file.o ... -Ldir ... -lfoo ...
-lfooWenn Sie ein anderes Programm oder DSO verknüpfen , können dem Linker sowohl gemeinsam genutzte als auch statische Bibliotheken über das einheitliche Protokoll angeboten werden. Diese Option weist den Linker an, die angegebenen oder Standard-Suchverzeichnisse zu durchsuchen, um entweder libfoo.sooder zu finden
libfoo.a. Wenn einer von beiden gefunden wird, wird diese Datei standardmäßig in die Verknüpfung eingegeben. Wenn beide Dateien im selben Suchverzeichnis gefunden werden, wird dies bevorzugt libfoo.so. Wenn libfoo.so, ausgewählt ist, fügt der Linker dieses DSO zur Laufzeitabhängigkeitsliste des von Ihnen erstellten Programms oder DSO hinzu. Wenn libfoo.aausgewählt, verwendet der Linker das Archiv als Auswahl von Objektdateien für die Verknüpfung mit der Ausgabedatei, falls erforderlich, genau dort und dann. Keine Laufzeitabhängigkeit von
libfoo.aselbst ist möglich; es kann nicht in einen Prozess abgebildet werden; Für den OS Loader bedeutet dies nichts.
Kopiert von https://stackoverflow.com/a/47924864/195787 .