Question

Quand je fais ls -l dans /usr/lib Je vois beaucoup de libs avec extension "sameName.so.*.*".

  1. Quelle est la signification de ces extensions?
  2. Pourquoi sont créés les liens logiciels? quels sont leur utilisation?

Un exemple vous aidera beaucoup à comprendre.

Était-ce utile?

La solution

Ceci est une astuce utilisée pour les fichiers d'objets partagés version. Il est un moyen d'éviter l'enfer DLL redoutée qui est arrivé à cause de l'enchaînement paresseux.

L'avantage de l'enchaînement paresseux (ou la liaison tardive) est que les composants de votre exécutable peuvent être modifiés sans réellement re relier ces executables. Cela permet des corrections de bugs dans les composants tiers sans avoir à expédier un nouvel exécutable, entre autres.

L'inconvénient est exactement le même que l'avantage. Votre exécutable peut trouver que les hypothèses qu'il a faites au sujet des bibliothèques sous-jacentes ont été modifiées et cela est susceptible de causer toutes sortes de problèmes.

Versioning des objets partagés est une façon d'éviter cela. Une autre serait de pas partager des objets du tout, mais qui a aussi des avantages et des inconvénients que je ne détaillerai pas ici.

A titre d'exemple, disons que vous avez la version 1 de xyz.so. Vous disposez d'un fichier et un lien symbolique vers ce fichier:

pax> ls -al xyz*
-rw-r--r--  1 pax paxgroup    12345 Nov 18  2009 xyz.so.1
lrwxrwxrwx  1 pax paxgroup        0 Nov 18  2009 xyz.so -> xyz.so.1

Maintenant, lorsque vous créez un fichier exécutable exe1, reliant avec xyz.so, il suivra le lien symbolique afin qu'il stocke xyz.so.1 dans l'exécutable comme la chose dont il a besoin à la charge lors de l'exécution.

De cette façon, lorsque vous mettez à niveau ainsi la bibliothèque partagée:

pax> ls -al xyz*
-rw-r--r--  1 pax paxgroup    12345 Nov 18  2009 xyz.so.1
-rw-r--r--  1 pax paxgroup    67890 Nov 18  2009 xyz.so.2
lrwxrwxrwx  1 pax paxgroup        0 Nov 18  2009 xyz.so -> xyz.so.2

votre exe1 exécutable d'origine sera toujours version 1 charge de l'objet partagé.

Cependant, vous créez des executables maintenant (comme exe2) sera lié à la version 2 de l'objet partagé.


Les détails de mise en œuvre réelle peut varier quelque peu (je fonde ma réponse sur Linux et Unix compatibles antérieures semble faire versioning un peu plus intelligemment que juste après les liens symboliques). IBM developerWorks a un bel article sur la façon dont il est fait .

Lorsque vous créez un objet partagé, vous donnez à la fois un nom et un soname. Ceux-ci sont utilisés pour installer l'objet partagé (ce qui crée à la fois l'objet et un lien vers elle).

Vous pouvez retrouver avec la situation:

pax> ls -al xyz*
-rw-r--r--  1 pax paxgroup    12345 Nov 18  2009 xyz.so.1.5
lrwxrwxrwx  1 pax paxgroup        0 Nov 18  2009 xyz.so.1 -> xyz.so.1.5
lrwxrwxrwx  1 pax paxgroup        0 Nov 18  2009 xyz.so -> xyz.so.1

avec xyz.so.1.5 possédant la SONAME de xyz.so.1.

Lorsque les liens de liens dans xyz.so, il suit les liens tout le chemin à xyz.so.1.5 et utilise son SONAME de xyz.so.1 pour stocker dans l'exécutable. Ensuite, lorsque vous run l'exécutable, il tente de charger xyz.so.1 qui pointera vers un xyz.so.1.N spécifique (version pas nécessairement 1.5).

Vous pouvez installer xyz.so.1.6 et mettre à jour le lien xyz.so.1 pour pointer vers elle au lieu et executables déjà liés utiliseraient qu'au lieu.

L'un des avantages de cette méthode multicouche est que vous pouvez avoir plusieurs bibliothèques potentiellement incompatibles du même nom (xyz.so.1.*, xyz.so.2.*) mais, dans chaque version majeure, vous pouvez librement les mettre à niveau car ils sont censés être compatibles .

Lorsque vous liez nouvelles executables:

  • Les liens avec xyz.so obtiendra la dernière version mineure de la dernière version majeure.
  • D'autres liens avec xyz.so.1 obtiendra la dernière version mineure d'une version majeure spécifique.
  • D'autres encore des liens avec xyz.so.1.2 auront une version mineure spécifique d'une version majeure spécifique.

Autres conseils

Il est un système versionnage pour les bibliothèques partagées . Chaque bibliothèque devrait avoir 3 noms:

  1. Nom: le nom de la bibliothèque réelle, libfoo.so.1.2.3
  2. "SONAME": le nom enregistré dans le fichier exécutable, et l'éditeur de liens dynamique de nom a l'air pour, libfoo.so.1.2. Ce nom est écrit dans la bibliothèque binaire lui-même, et sera enregistré dans le fichier exécutable au moment de la liaison. Il est généralement un lien symbolique vers le vrai nom de la bibliothèque (généralement dernière version).
  3. nom Linker: le nom que vous donnez à l'éditeur de liens lors de la construction de votre programme. liens habituellement la dernière SONAME.

Exemple

Disons que vous avez la version libfoo 1 installé: libfoo.so -> libfoo.so.1.0 -> libfoo.so.1.0.0. Vous construisez votre bar programme avec -lfoo. il relie maintenant libfoo et charge libfoo.so.1.0 lors de l'exécution en raison de SONAME. Ensuite, vous passez à une libfoo.so.1.0.1 patché mais compatible binaire en remplaçant binaire réel. bar encore des liens vers libfoo.so.1.0 et n'a pas besoin d'être reconstruit.

Maintenant, imaginez que vous voulez construire un nouveau baz de programme qui profite des changements incompatibles dans libfoo V1.1. Vous installez une nouvelle version et votre système maintenant deux versions installées en parallèle:

  1. libfoo.so.1.0 -> libfoo.so.1.0.1
  2. libfoo.so -> libfoo.so.1.1 -> libfoo.so.1.1.0

Note nom l'éditeur de liens a été mis à jour à la dernière version (ce qui est la version correspondant aux en-têtes installés à l'/usr/include).

Vous construisez baz, et des liens vers libfoo.so et charges libfoo.so.1.1 lors de l'exécution. Non pas que bar fonctionne toujours contre libfoo.so.1.0 et n'a pas besoin d'être mis à jour.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top