cuál son .so *. *. * libs
Pregunta
Cuando hago ls -l
en /usr/lib
veo un montón de librerías con extensión "sameName.so.*.*"
.
- ¿Cuál es el significado de estas extensiones?
- ¿Por qué se crean enlaces simbólicos? ¿cuáles son su uso?
Un ejemplo ayudará mucho en la comprensión.
Solución
Este es un truco utilizado para compartir archivos objeto de versión. Es una manera de evitar el infierno DLL temido, que se produjo debido a la vinculación perezoso.
La ventaja de los vínculos vago (o el enlace en tiempo) es que los componentes de su ejecutable se pueden cambiar sin tener que volver a vincular los archivos ejecutables. Esto permite la corrección de errores en componentes de terceros, sin tener que enviar un nuevo ejecutable, entre otras cosas.
La desventaja es exactamente la misma que la ventaja. El ejecutable puede encontrar que los supuestos que hizo sobre las bibliotecas subyacentes han cambiado y es probable que esto causar todo tipo de problemas.
Control de versiones de objetos compartidos es una forma de evitar esto. Otra sería no objetos comparten en absoluto, sino que también tiene pros y contras que no voy a entrar en aquí.
A modo de ejemplo, digamos que usted tiene la versión 1 de xyz.so
. Tiene un archivo y un enlace simbólico a ese archivo:
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
Ahora, cuando se crea un archivo ejecutable exe1
, vinculándolo con xyz.so
, se seguirá el enlace simbólico para que almacene xyz.so.1
en el ejecutable como lo necesita cargar en tiempo de ejecución.
De esta manera, cuando se actualiza la biblioteca compartida de este modo:
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
exe1
el ejecutable original será Todavía carga de la versión 1 del objeto compartido.
Sin embargo, cualquier ejecutable que crear ahora (como exe2
) se vinculará con la versión 2 del objeto compartido.
Los detalles reales de implementación pueden variar un poco (estoy basando mi respuesta en UNIXes anteriores y Linux parece hacer versiones un poco más inteligente que simplemente seguir enlaces simbólicos). IBM developerWorks tiene un buen artículo sobre cómo se hace aquí .
Cuando se crea un objeto compartido, que le dan tanto un nombre real y un soname
. Estos se utilizan para instalar el objeto compartido (que crea el objeto y un enlace a ella).
Por lo que puede terminar con la situación:
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
con xyz.so.1.5
que posea la SONAME
de xyz.so.1
.
Cuando los enlaces de engarce en xyz.so
, se sigue los enlaces de todo el camino a xyz.so.1.5
y utiliza su SONAME
de xyz.so.1
a la tienda en el ejecutable. Entonces, cuando Ejecutar el ejecutable, se trata de xyz.so.1
carga que apuntar a un xyz.so.1.N
específica (no necesariamente la versión 1.5).
Por lo que podría instalar xyz.so.1.6
y actualizar el enlace xyz.so.1
a punto a la misma vez y ejecutables vinculados ya-usarían en su lugar.
Una de las ventajas de este método de múltiples capas es que se pueden tener varias bibliotecas potencialmente incompatibles con el mismo nombre (xyz.so.1.*
, xyz.so.2.*
), pero, dentro de cada versión principal, que ellos libremente puede actualizar, ya que se supone que deben ser compatibles .
Al vincular nuevos ejecutables:
- Los vinculación con
xyz.so
obtendrá la última versión menor de la última versión principal. - Otros vinculan con
xyz.so.1
obtendrá la última versión menor de una gran versión específica. - Y otros que vinculan con
xyz.so.1.2
obtendrán una versión específica menor de una gran versión específica.
Otros consejos
Es un esquema de versiones para las bibliotecas compartidas . Cada biblioteca debe tener 3 nombres:
- Nombre real: el nombre de la biblioteca real,
libfoo.so.1.2.3
- "SONAME": el nombre registrado en el ejecutable, y las miradas nombre del enlazador dinámico para,
libfoo.so.1.2
. Este nombre se escribe realmente dentro de la biblioteca binaria sí mismo, y se registrará en el archivo ejecutable en tiempo de enlace. Por lo general es un enlace simbólico con el nombre real de la biblioteca (por lo general la última versión). - nombre del enlazador: el nombre que le asigne el enlazador en la construcción de su programa. Por lo general, contiene las últimas SONAME.
Ejemplo
Supongamos que tiene libfoo
versión instalada 1: libfoo.so
-> libfoo.so.1.0
-> libfoo.so.1.0.0
. A construir su bar
programa con -lfoo
. ahora une a libfoo
y se carga libfoo.so.1.0
en tiempo de ejecución debido a SONAME. A continuación, se actualiza a una libfoo.so.1.0.1
parcheado, pero con capacidad para un binaria mediante la sustitución binaria real. bar
aún enlaces a libfoo.so.1.0
y no necesita ser reconstruido.
Ahora imagina que quiere construir un nuevo baz
programa que se aprovecha de cambios incompatibles en v1.1 libtal. Instalar una nueva versión y su sistema ahora tiene dos versiones instaladas en paralelo:
-
libfoo.so.1.0
->libfoo.so.1.0.1
-
libfoo.so
->libfoo.so.1.1
->libfoo.so.1.1.0
Nombre de la nota engarce se actualiza a la última versión (esta es la versión que corresponde a los colectores instalados en /usr/include
).
A construir baz
, y se une a libfoo.so
y cargas libfoo.so.1.1
en tiempo de ejecución. No es que bar
todavía corre contra libfoo.so.1.0
y no necesita ser actualizado.