Diese Frage ist nicht spezifisch für Solaris.
Wenn Sie eine gemeinsam genutzte Bibliothek (oder eine Software, die eine gemeinsam genutzte Bibliothek bereitstellt) installieren, erhalten Sie drei Dateien, die alle ähnlich aussehen, aber unterschiedliche Zwecke haben.
libfoo.so.1.0.0
- Dies ist die (reguläre) Datendatei. Es enthält die Bibliothek selbst. Sie können mehrere davon mit unterschiedlichen Versionen haben. In dieser Datei befindet sich ein ELF-Feld namens SONAME , das auf gesetzt ist libfoo.so.1
. Führen Sie unter Linux aus, objdump -p libfoo.so.1.0.0 | grep SONAME
um dies herauszufinden.
libfoo.so
→ libfoo.so.1.0.0
- Dies ist ein Symlink, der beim Kompilieren von Software gegen libfoo verwendet wird. Wenn Sie -lfoo
den Linker angeben , wird genau danach gesucht libfoo.so
. Normalerweise libfoo.so
handelt es sich nie um eine reguläre Datei, sondern immer um einen Symlink, der auf die Version von libfoo verweist, die Sie zum Verknüpfen verwenden möchten. In einer komplexen Build-Umgebung können mehrere Versionen der Bibliothek vorhanden sein. Über diesen Symlink können Sie auswählen, mit welcher Version Sie eine Verknüpfung herstellen möchten.
libfoo.so.1
→ libfoo.so.1.0.0
- Dies ist auch ein Symlink, der verwendet wird, wenn Sie Binärdateien ausführen, die Ihre Bibliothek benötigen. Erinnerst du dich an das SONAME-Feld, das ich erwähnt habe? Wenn Sie eine Binärdatei mit libfoo verknüpfen, zeichnet die Binärdatei den SONAME der Bibliothek auf und verwendet ihn zur Laufzeit.
Mit diesem Setup können Sie mehrere Versionen derselben Bibliothek nebeneinander installieren. Unterschiedliche Binärdateien erfordern möglicherweise unterschiedliche Versionen der Bibliothek, und jede Binärdatei findet die richtige Version der Bibliothek. Normalerweise wird der SONAME der Bibliothek vom Upstream geändert, wenn eine rückwärts inkompatible API-Änderung vorliegt. Alle alten Binärdateien verwenden weiterhin die alte API, während neu verknüpfte Binärdateien die neue verwenden.
Einige Verpackungsprojekte, Debian wäre ein Beispiel, verwenden unterschiedliche Paketnamen für unterschiedliche Versionen einer Bibliothek. Auf diese Weise können Sie jede Version der gemeinsam genutzten Bibliothek unabhängig voneinander installieren und deinstallieren.
Es gibt einige Randfälle. Beispielsweise können Abhängigkeiten zwischen gemeinsam genutzten Bibliotheken dazu führen, dass zwei Versionen gleichzeitig abgerufen werden. Erwägen:
foo → libbar.so.1, libbaz.so.1
libbar.so.1 → libbaz.so.1
Stellen Sie sich vor, wir installieren eine neue Version von libbaz und kompilieren foo neu. Jetzt haben wir:
foo → libbar.so.1, libbaz.so.2
libbar.so.1 → libbaz.so.1
Zur Laufzeit wird foo geladen libbaz.so.2
und libbar.so.1
und libbar.so.1
wird geladen libbaz.so.1
. Sehen Sie das Problem? Es werden zwei Versionen von Libbaz gleichzeitig geladen. Ich bin nicht ganz sicher, was die genaue Konsequenz in Bezug auf das Layout des Codes im Speicher ist, aber in der Praxis führt dies zu Abstürzen.