Pourquoi ne puis-je pas installer plusieurs versions d'une bibliothèque partagée?

10

Il y a souvent des cas où un certain programme dépendra de la version de la bibliothèque xy et un autre de xz mais, à ma connaissance, aucun gestionnaire de paquets ne me permettra d'installer à la fois xy et xz Parfois, ils autoriseront les deux versions principales (telles que qt4 et qt5, qui peuvent être installés en même temps), mais (apparemment) jamais de versions mineures.

Pourquoi est-ce? Comme dans, quel est le facteur limitant qui l'empêche? Je suppose qu'il doit y avoir une bonne raison de ne pas autoriser cette fonctionnalité apparemment utile. Par exemple, n'y a-t-il pas un champ pour indiquer quelle version charger lors du chargement d'un objet partagé et donc aucun moyen pour Linux de savoir comment décider lequel charger? Ou n'y a-t-il vraiment aucune raison à cela? Comme toutes les versions mineures sont censées être compatibles de toute façon ou quelque chose?

Tyler
la source

Réponses:

13

En fait, vous pouvez installer plusieurs versions d'une bibliothèque partagée si cela est fait correctement.

Les bibliothèques partagées sont généralement nommées comme suit:

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

Ensuite, il existe des liens symboliques vers la bibliothèque sous les noms suivants:

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

Lorsqu'un développeur établit un lien avec la bibliothèque pour produire un binaire, c'est le nom de fichier qui se termine par .socelui que l'éditeur de liens trouve. Il ne peut en effet y avoir qu'une seule installation à la fois pour n'importe quelle donnée, <name>mais cela signifie seulement qu'un développeur ne peut pas cibler plusieurs versions différentes d'une bibliothèque en même temps. Avec les gestionnaires de packages, ce .solien symbolique fait partie d'un -devpackage distinct que seuls les développeurs doivent installer.

Lorsque l'éditeur de liens trouve un fichier dont le nom se termine par .soet l'utilise, il recherche dans cette bibliothèque un champ appelé soname . Le soname indique à l'éditeur de liens quel nom de fichier intégrer dans le binaire résultant et donc quel nom de fichier sera recherché lors de l'exécution. Le soname est censé être réglé sur lib<name>.so.<api-version>.

Par conséquent, au moment de l'exécution, l'éditeur de liens dynamique cherchera lib<name>.so.<api-version>et utilisera cela.

L'intention est que:

  • <minor>les mises à niveau ne modifient pas l'API de la bibliothèque et lorsque le <minor>fichier passe à une version supérieure, il est prudent de laisser tous les binaires passer à la nouvelle version. Étant donné que les fichiers binaires recherchent tous la bibliothèque sous le lib<name>.so.<api-version>nom, qui est un lien symbolique vers la dernière version installée lib<name>.so.<api-version>.<minor>, ils obtiennent la mise à niveau.
  • <api-version>les mises à niveau modifient l'API de la bibliothèque et il n'est pas sûr de laisser les applications binaires existantes utiliser la nouvelle version. Dans le cas où le <api-version>est modifié, puisque ces applications recherchent le nom lib<name>.so.<api-version>mais avec une valeur différente pour <api-version>, elles ne prendront pas la nouvelle version.

Les gestionnaires de packages ne regroupent pas souvent plus d'une version de la même bibliothèque dans la même version de distribution car la distribution entière, y compris tous les binaires qui utilisent la bibliothèque, est généralement compilée pour utiliser une version cohérente de chaque bibliothèque avant la distribution. libéré. S'assurer que tout est cohérent et que tout dans une distribution est compatible avec tout le reste est une grande partie de la charge de travail pour les distributeurs.

Mais vous pouvez facilement vous retrouver avec plusieurs versions d'une bibliothèque si vous avez mis à niveau votre système d'une version de votre distraction à une autre et que certains packages plus anciens nécessitent des versions de bibliothèque plus anciennes. Exemple:

  • libmysqlclient16 d'une ancienne Debian, contient libmysqlclient.so.16.0.0et lien symbolique libmysqlclient.so.16.
  • libmysqlclient18 de Debian actuelle, contient libmysqlclient.so.18.0.0et lien symbolique libmysqlclient.so.18.
Celada
la source
4

Cette fonctionnalité n'est pas interdite, elle n'est tout simplement pas très courante en raison du fonctionnement de la plupart des bibliothèques de numérotation et en raison de l'inconvénient des changements de nom de package.

Si vous utilisez un schéma de numéro de version en pointillé XYZ La version "micro" Z change souvent sur les corrections de bogues, le numéro "mineur" Y change sur les modifications rétrocompatibles et le numéro de version "majeur" X doit changer sur les changements d'API (et parfois le fait sur fonctionnalités supplémentaires majeures).

Il ne devrait jamais y avoir de raison pour que vous ne vouliez pas que les derniers bugs soient corrigés, et les modifications rétrocompatibles ne devraient pas non plus casser votre logiciel.

Si la bibliothèque est développée de cette façon, vous devriez toujours pouvoir remplacer XYZ par X. (Y + m). (Z + n). pour tout m et n donné. C'est-à-dire que vous devriez toujours pouvoir remplacer votre bibliothèque par la dernière de la même série de nombres majeurs. Et si les développeurs de la bibliothèque sont prudents et que le prochain numéro majeur est compatible (par exemple par l'annonce pour déprécier les choses, mais pas encore les supprimer), vous pouvez même utiliser le prochain numéro majeur.

Pour les développeurs de packages, cela signifie qu'ils peuvent utiliser le nom avec un seul, voire aucun nom de numéro pour vous donner la dernière version en mettant simplement à jour le package. S'ils expédient une bibliothèque dans un package, abc2ils doivent passer par des cercles pour déplacer leur propre logiciel qui comptait sur la abc2mise à niveau pour l'utiliser abc3, parfois avec des packages de transition. Il est plus pratique de supprimer le numéro de version principal d'une bibliothèque si cela fonctionne pour la plupart des packages dépendants. Donc, même si les deux abc2et abc3devraient être disponibles à un moment donné dans une distribution, abc3est souvent appelé abc(tout comme il l' abc2était quand il n'y en avait pas abc3encore), et dès qu'aucun package ne dépend de abc2la distribution, il devient possible de le supprimerabc2 tout à fait.

Le schéma de numérotation n'est pas suivi de manière uniforme, mais je ne peux qu'imaginer qu'avec l'avènement d'Internet, la diffusion d'informations sur la façon d'utiliser un tel schéma, et la pression des utilisateurs de la bibliothèque (y compris les développeurs de distribution) pour rendre les choses importantes comme la rétrocompatibilité claires sans avoir à lire un fichier CHANGES inclus dans la bibliothèque, ont contribué à ce que cela soit devenu plus courant.

Un exemple de compteur, mais pas d'une bibliothèque, est l'interpréteur python, qui n'est pas compatible sur ses objets partagés et le format de décapage lors d'un changement mineur de nombre. Par conséquent, vous verrez des packages pour python (le dernier de la série 2.7), et python3 (le dernier de la série python3.4 actuellement) ainsi que des packages explicites pour python 2.6 (qui ne deviennent pas moins courants) ainsi que python 3.3.

Anthon
la source