Warum kann ich nicht mehrere Versionen einer gemeinsam genutzten Bibliothek installieren?

10

Es gibt oft Fälle, in denen ein bestimmtes Programm von der Bibliotheksversion xy und ein anderes von xz abhängt. Soweit mir bekannt ist, erlaubt mir kein Paketmanager, sowohl xy als auch xz zu installieren. Manchmal erlauben sie beide Hauptversionen (z qt4 und qt5, die gleichzeitig installiert werden können), aber (scheinbar) nie kleinere Versionen.

Warum ist das? Was ist der einschränkende Faktor, der dies verhindert? Ich gehe davon aus, dass es einen guten Grund geben muss, diese scheinbar nützliche Funktionalität nicht zuzulassen. Gibt es beispielsweise kein Feld, in dem angegeben wird, welche Version beim Laden eines gemeinsam genutzten Objekts geladen werden soll, und Linux daher nicht wissen kann, wie zu entscheiden ist, welche geladen werden soll? Oder gibt es wirklich keinen Grund dafür? Wie sollen alle Nebenversionen sowieso kompatibel sein oder so?

Tyler
quelle

Antworten:

12

Tatsächlich können Sie mehrere Versionen einer gemeinsam genutzten Bibliothek installieren, wenn dies ordnungsgemäß durchgeführt wurde.

Freigegebene Bibliotheken werden normalerweise wie folgt benannt:

lib<name>.so.<api-version>.<minor>

Als nächstes gibt es Symlinks zur Bibliothek unter den folgenden Namen:

lib<name>.so
lib<name>.so.<api-version>

Wenn ein Entwickler eine Verknüpfung mit der Bibliothek herstellt, um eine Binärdatei zu erstellen, wird der Dateiname .sovom Linker gefunden. Es kann zwar jeweils nur eine davon installiert sein <name>, dies bedeutet jedoch nur, dass ein Entwickler nicht mehrere verschiedene Versionen einer Bibliothek gleichzeitig als Ziel festlegen kann. Bei Paketmanagern ist dieser .soSymlink Teil eines separaten -devPakets, das nur Entwickler installieren müssen.

Wenn der Linker eine Datei mit einem Namen findet, der auf endet, .sound diese verwendet, sucht er in dieser Bibliothek nach einem Feld namens Soname . Der Soname teilt dem Linker mit, welcher Dateiname in die resultierende Binärdatei eingebettet werden soll und welcher Dateiname zur Laufzeit gesucht wird. Der Soname soll eingestellt sein lib<name>.so.<api-version>.

Daher sucht lib<name>.so.<api-version>und verwendet der dynamische Linker zur Laufzeit dies .

Die Absicht ist:

  • <minor>Durch Upgrades wird die API der Bibliothek nicht geändert. Wenn die <minor>Version auf eine höhere Version umgestellt wird, können alle Binärdateien sicher auf die neue Version aktualisiert werden. Da alle Binärdateien die Bibliothek unter dem lib<name>.so.<api-version>Namen suchen , der ein Symlink zur zuletzt installierten Bibliothek ist lib<name>.so.<api-version>.<minor>, erhalten sie das Upgrade.
  • <api-version>Upgrades ändern die API der Bibliothek, und es ist nicht sicher, vorhandene Binäranwendungen die neue Version verwenden zu lassen. In dem Fall, dass das <api-version>geändert wird, werden diese Anwendungen die neue Version nicht übernehmen , da diese Anwendungen nach dem Namen suchen, lib<name>.so.<api-version>aber einen anderen Wert für <api-version>haben.

Paketmanager packen häufig nicht mehr als eine Version derselben Bibliothek innerhalb derselben Distributionsversion, da die gesamte Distribution, einschließlich aller Binärdateien, die die Bibliothek verwenden, normalerweise so kompiliert wird, dass vor der Distribution eine konsistente Version jeder Bibliothek verwendet wird freigegeben. Es ist ein großer Teil der Arbeitsbelastung für Distributoren, sicherzustellen, dass alles konsistent ist und dass alles in einer Distribution mit allem anderen kompatibel ist.

Es kann jedoch leicht zu mehreren Versionen einer Bibliothek kommen, wenn Sie Ihr System von einer Version Ihrer Distribution auf eine andere aktualisiert haben und noch einige ältere Pakete haben, für die ältere Bibliotheksversionen erforderlich sind. Beispiel:

  • libmysqlclient16 aus einem älteren Debian, enthält libmysqlclient.so.16.0.0und symlink libmysqlclient.so.16.
  • libmysqlclient18 aus dem aktuellen Debian, enthält libmysqlclient.so.18.0.0und symlink libmysqlclient.so.18.
Celada
quelle
4

Diese Funktionalität ist nicht unzulässig, sie ist jedoch aufgrund der Funktionsweise der meisten Bibliotheksnummern und der Unannehmlichkeiten bei Änderungen des Paketnamens nicht sehr verbreitet.

Wenn ein gepunktetes Versionsnummernschema verwendet wird XYZ Die "Mikro" -Version Z ändert sich häufig bei Bugfixes, die "Neben" -Nummer Y ändert sich bei abwärtskompatiblen Änderungen und die "Haupt" -Versionsnummer X muss sich bei API-Änderungen ändern (und manchmal auch wichtige zusätzliche Funktionalität).

Es sollte niemals einen Grund geben, warum Sie nicht möchten, dass die neuesten Fehler behoben werden, und abwärtskompatible Änderungen sollten auch Ihre Software nicht beschädigen.

Wenn die Bibliothek auf diese Weise entwickelt wurde, sollten Sie immer in der Lage sein, XYZ durch X zu ersetzen. (Y + m). (Z + n). für jedes gegebene m und n. Das heißt, Sie sollten immer in der Lage sein, Ihre Bibliothek durch die neueste in derselben Hauptnummernserie zu ersetzen. Und wenn die Bibliotheksentwickler vorsichtig sind und die nächste Hauptnummer kompatibel ist (z. B. durch die Ankündigung, Dinge zu verwerfen, aber noch nicht zu entfernen), können Sie sogar die nächste Hauptnummer verwenden.

Für Paketentwickler bedeutet dies, dass sie den Namen mit nur einem oder gar keinem Nummernnamen verwenden können, um die neueste Version zu erhalten, indem sie nur das Paket aktualisieren. Wenn sie eine Bibliothek in einem Paket versenden , abc2dann müssen sie durch Reifen gehen , um ihre eigene Software zu bewegen , die verließen auf , abc2um den Einsatz zu aktualisieren abc3, manchmal mit Übergang von Paketen. Es ist bequemer, die Hauptversionsnummer aus einer Bibliothek wegzulassen, wenn dies für die meisten abhängigen Pakete funktioniert. Selbst wenn beide abc2und abc3irgendwann in einer Distribution verfügbar sein sollten, abc3wird dies häufig aufgerufen abc(genau wie abc2es aufgerufen wurde, als es noch keine abc3gab), und sobald keine Pakete abc2innerhalb der Distribution abhängen, kann es gelöscht werdenabc2 insgesamt.

Das Nummerierungsschema wird nicht einheitlich befolgt, aber ich kann mir nur vorstellen, dass mit dem Aufkommen des Internets Informationen über die Verwendung eines solchen Schemas verbreitet werden und der Druck von Bibliotheksbenutzern (einschließlich Distributionsentwicklern), wichtige Dinge wie die Abwärtskompatibilität ohne klar zu machen Das Lesen einer in der Bibliothek enthaltenen CHANGES-Datei hat dazu beigetragen, dass dies häufiger geworden ist.

Ein Gegenbeispiel, jedoch nicht für eine Bibliothek, ist der Python-Intpreter, der bei einer geringfügigen Änderung der Anzahl nicht mit den gemeinsam genutzten Objekten und dem Beizformat kompatibel ist. Daher sehen Sie Pakete für Python (das neueste in der 2.7-Serie) und Python3 (das neueste in der aktuellen Python3.4-Serie) sowie explizite Pakete für Python 2.6 (nicht weniger verbreitet) sowie Python 3.3.

Anthon
quelle