Wie funktionieren SO-Nummern (Shared Object)?

Wie funktionieren SO-Nummern (Shared Object)?

Mir ist bewusst, dass gemeinsam genutzte Objekte unter Linux „so-Nummern“ verwenden, nämlich dass verschiedene Versionen eines gemeinsam genutzten Objekts unterschiedliche Erweiterungen erhalten, zum Beispiel:

  • example.so.1
  • example.so.2

Ich verstehe, dass die Idee darin besteht, zwei verschiedene Dateien zu haben, sodass zwei Versionen einer Bibliothek auf einem System existieren können (im Gegensatz zur „DLL-Hölle“ unter Windows). Ich würde gerne wissen, wie das in der Praxis funktioniert. Oft sehe ich, dass es example.sosich tatsächlich um einen symbolischen Link handelt, example.so.2wo .2sich die neueste Version befindet. Wie identifiziert dann eine Anwendung, die von einer älteren Version abhängt, example.sodiese richtig? Gibt es Regeln, welche Nummern verwendet werden müssen? Oder ist das einfach Konvention? Ist es so, dass, anders als unter Windows, wo Software-Binärdateien zwischen Systemen übertragen werden, ein System, das eine neuere Version eines gemeinsam genutzten Objekts hat, beim Kompilieren aus der Quelle automatisch mit der älteren Version verknüpft wird?

Ich vermute, dass dies damit zusammenhängt, ldconfigbin mir aber nicht sicher, in welchem ​​Zusammenhang.

Antwort1

Binärdateien selbst wissen, von welcher Version einer gemeinsam genutzten Bibliothek sie abhängen, und fordern diese gezielt an. Sie können verwenden, lddum die Abhängigkeiten anzuzeigen. Meine lssind:

$ ldd /bin/ls
    linux-gate.so.1 =>  (0xb784e000)
    librt.so.1 => /lib/librt.so.1 (0xb782c000)
    libacl.so.1 => /lib/libacl.so.1 (0xb7824000)
    libc.so.6 => /lib/libc.so.6 (0xb76dc000)
    libpthread.so.0 => /lib/libpthread.so.0 (0xb76c3000)
    /lib/ld-linux.so.2 (0xb784f000)
    libattr.so.1 => /lib/libattr.so.1 (0xb76bd000)

Wie Sie sehen, zeigt es zB auf libpthread.so.0, nicht nur auf libpthread.so.


Der Grund für den symbolischen Link ist der Linker. Wenn Sie direkt verlinken möchten libpthread.so, geben Sie gccdas Flag ein -lpthreadund es fügt automatisch libPräfix und Suffix hinzu. Sie können ihm nicht sagen, dass er das Suffix hinzufügen soll, also verweist der symbolische Link auf die neueste Version der Bibliothek, um dies zu ermöglichen..so.so.0

Antwort2

Die Nummern in den gemeinsam genutzten Bibliotheken sind in Linux die Konvention zur Identifizierung der API einer Bibliothek. Normalerweise ist das Format:

libFOO.so.MAJOR.MINOR

Und wie Sie bemerkt haben, gibt es normalerweise einen symbolischen Link von libFOO.so zu libFOO.so.MAJOR.MINOR. ldconfig ist dafür verantwortlich, diesen Link auf die neueste Version zu aktualisieren.

Der MAJOR wird normalerweise erhöht, wenn sich die API ändert (neue Einstiegspunkte werden entfernt oder die Parameter oder Typen geändert). Der MINOR wird normalerweise für Bugfix-Releases erhöht oder wenn neue APIs eingeführt werden, ohne vorhandene APIs zu beschädigen.

Eine ausführlichere Diskussion finden Sie hier:Gemeinsam genutzte Bibliotheken analysieren

Antwort3

Gemeinsam genutzte Bibliotheken sollten nach folgendem Schema versioniert werden:

blah.so.X.Y.Z

Wo

  • X = abwärtsinkompatible ABI-Version
  • Y = abwärtskompatible ABI-Version
  • Z = Nur interne Änderungen – keine Änderung am ABI

Normalerweise wird nur die erste Ziffer angezeigt, hello.so.1da nur die erste Ziffer zur Identifizierung der „Version“ der Bibliothek erforderlich ist, da alle anderen Ziffern abwärtskompatibel sind.

ldconfigverwaltet eine Tabelle, die angibt, welche gemeinsam genutzten Bibliotheken auf einem System verfügbar sind und wo der Pfad zu dieser Bibliothek liegt. Sie können dies überprüfen, indem Sie Folgendes ausführen:

ldconfig -p

Wenn ein Paket für etwas wie Red Hat erstellt wird, werden die in der Binärdatei aufgerufenen gemeinsam genutzten Bibliotheken beim RPM-Build-Zeitpunkt gesucht und als Abhängigkeiten des Pakets hinzugefügt. Wenn Sie also das Paket installieren, sucht das Installationsprogramm hello.so.1durch Überprüfen nach, ob es auf dem System installiert ist oder nicht ldconfig.

Sie können die Abhängigkeiten eines Pakets anzeigen, indem Sie beispielsweise Folgendes tun:

rpm -qpR hello.rpm

Dieses System ermöglicht (im Gegensatz zu Windows) die Installation mehrerer Versionen hello.soauf einem System und die gleichzeitige Verwendung durch verschiedene Anwendungen.

Antwort4

libNAME.so ist der Dateiname, der vom Compiler/Linker verwendet wird, wenn er zum ersten Mal nach einer durch -lNAME angegebenen Bibliothek sucht. In einer gemeinsam genutzten Bibliotheksdatei befindet sich ein Feld namens SONAME. Dieses Feld wird festgelegt, wenn die Bibliothek selbst zum ersten Mal durch den Build-Prozess in ein gemeinsam genutztes Objekt (so) eingebunden wird. Dieser SONAME ist eigentlich das, was ein Linker in einer ausführbaren Datei speichert, je nachdem, welches gemeinsam genutzte Objekt damit verknüpft ist. Normalerweise hat der SONAME die Form libNAME.so.MAJOR und wird immer dann geändert, wenn die Bibliothek mit vorhandenen, damit verknüpften ausführbaren Dateien inkompatibel wird. Beide Hauptversionen der Bibliothek können bei Bedarf installiert bleiben (obwohl nur eine für die Entwicklung als libNAME.so angezeigt wird). Um außerdem ein einfaches Upgrade zwischen Nebenversionen einer Bibliothek zu unterstützen, ist libNAME.so.MAJOR normalerweise ein Link zu einer Datei wie libNAME.so.MAJOR.MINOR. Eine neue Nebenversion kann installiert werden, und sobald dies abgeschlossen ist, wird der Link zur alten Nebenversion so geändert, dass er auf die neue Nebenversion verweist, wodurch alle neuen Ausführungen sofort aktualisiert werden, um die aktualisierte Bibliothek zu verwenden. Siehe auch meine Antwort aufLinux, GNU GCC, ld, Versionsskripte und das ELF-Binärformat – Wie funktioniert das?

verwandte Informationen