Was ist Ranlib?

13

Ich benutze seit einiger Zeit ein MacOSX-System, habe aber erst vor kurzem angefangen, mich in die Eingeweide zu stürzen. Ich habe eine Anleitung gefunden, die mir sagt, dass ich 'sudo ranlib /usr/local/lib/libjpeg.a' (Installation von libjpeg) ausführen soll. Ich habe das Ranlib-Handbuch gelesen und versucht, online danach zu suchen. Ich verstehe einfach nicht. Welche Ressourcen muss ich nachschlagen, um mehr zu erfahren, oder kann jemand eine kurze Erklärung zu ihrer Verwendung geben? Danke im Voraus!

Ying
quelle

Antworten:

7

ranlibFügt Objektdateien in einer statischen Bibliothek hinzu oder aktualisiert sie . Linker können beim Verknüpfen statische Bibliotheken verwenden, um Symbole bereitzustellen , die der Code für den Betrieb benötigt (im Gegensatz zu dem Loader , der sie in dynamischen Bibliotheken sucht, wenn er die ausführbare Datei ausführt).

Ignacio Vazquez-Abrams
quelle
Hallo Ignacio, danke für die Antwort. Bedeutet dies, dass Ranlib, wenn ich es in einer Bibliothek ausführe, jedes Mal verwendet werden kann, wenn ein Linker versucht, darauf zu verweisen? Wie wird es entfernt?
Ying
ranlibwird zum Erstellen und Ändern der Bibliotheken verwendet. Es liegt an dem Linker, sie zu verwenden, normalerweise indem er den Speicherort und / oder den Namen der Bibliothek in der Befehlszeile übergibt. Weitere Informationen finden Sie in den Argumenten -Lund -lzu gcc.
Ignacio Vazquez-Abrams
5
Aber macht das nicht arauch? Was ist der Unterschied?
Urwolf
18

Diese Beschreibung sieht ziemlich klar aus: http://sourceware.org/binutils/docs/binutils/ranlib.html

Wenn Sie also eine Sammlung von Objektdateien archivieren, sagen Sie:

$ ar r fruits.a apple.o orange.o pineapple.o

Dann rennen

$ ranlib fruits.a

Erstellt einen Index des Inhalts von Früchte.a und speichert den Index in Früchten.a. Dies ist nützlich für die Verknüpfung und für den Fall, dass sich die Objekte gegenseitig aufrufen.

Gast McGuesterson
quelle
"ranlib generiert einen Index zum Inhalt eines Archivs und speichert ihn im Archiv". Das klingt eher nach etwas, mit dem man sich kombinieren kann, tarund ich würde sagen, nicht sehr klar.
Codebling
9

ranlib generiert einen Index zum Inhalt eines Archivs und speichert ihn im Archiv. Der Index listet jedes Symbol auf, das von einem Mitglied eines Archivs definiert wurde, bei dem es sich um eine verschiebbare Objektdatei handelt. Ein Archiv mit einem solchen Index beschleunigt die Verknüpfung mit der Bibliothek und ermöglicht es Routinen in der Bibliothek, sich gegenseitig aufzurufen, ohne Rücksicht auf ihre Platzierung im Archiv.

Quelle: Ranlib-Manpage

Albert
quelle
2

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 .

Royi
quelle