it-swarm-es.tech

¿Cómo funcionan los números SO (objeto compartido))?

Soy consciente de que los objetos compartidos en Linux usan "números", es decir, que las diferentes versiones de un objeto compartido reciben extensiones diferentes, por ejemplo:

  • example.so.1
  • example.so.2

Entiendo que la idea es tener dos archivos distintos de modo que puedan existir dos versiones de una biblioteca en un sistema (a diferencia de "DLL Hell" en Windows). ¿Me gustaría saber cómo funciona esto en la práctica? A menudo, veo que example.so es de hecho un enlace simbólico a example.so.2 dónde .2 es la última versión. ¿Cómo funciona una aplicación dependiendo de una versión anterior de example.so identificarlo correctamente? ¿Hay alguna regla sobre qué números se deben usar? ¿O es simplemente una convención? ¿Es el caso que, a diferencia de Windows, donde los archivos binarios de software se transfieren entre sistemas, si un sistema tiene una versión más nueva de un objeto compartido, se vincula automáticamente a la versión anterior al compilar desde la fuente?

Sospecho que esto está relacionado con ldconfig pero no estoy seguro de cómo.

127
user119

Los propios binarios saben de qué versión de una biblioteca compartida dependen y lo solicitan específicamente. Puede usar ldd para mostrar las dependencias; los míos para ls son:

$ ldd /bin/ls
    linux-gate.so.1 =>  (0xb784e000)
    librt.so.1 => /lib/librt.so.1 (0xb782c000)
    libacl.so.1 => /lib/libacl.so.1 (0xb7824000)
    libc.so.6 => /lib/libc.so.6 (0xb76dc000)
    libpthread.so.0 => /lib/libpthread.so.0 (0xb76c3000)
    /lib/ld-linux.so.2 (0xb784f000)
    libattr.so.1 => /lib/libattr.so.1 (0xb76bd000)

Como puede ver, apunta a, p. libpthread.so.0, No solo libpthread.so.


La razón del enlace simbólico es para el enlazador. Cuando quieres vincular contra libpthread.so directamente, le das a gcc la bandera -lpthread, y agrega el prefijo lib y .so sufijo automáticamente. No puede decirle que agregue el .so.0 sufijo, por lo que el enlace simbólico apunta a la versión más reciente de la biblioteca para facilitar que

91
Michael Mrozek

Los números en las bibliotecas compartidas son convenciones utilizadas en Linux para identificar la API de una biblioteca. Por lo general, el formato es:

libFOO.so.MAJOR.MINOR

Y como notó, generalmente hay un enlace simbólico de libFOO.so a libFOO.so.MAJOR.MINOR. ldconfig es responsable de actualizar este enlace a la versión más reciente.

El MAYOR generalmente se incrementa cuando cambia la API (se eliminan nuevos puntos de entrada o se cambian los parámetros o tipos). El MENOR generalmente se incrementa para las versiones de corrección de errores o cuando se introducen nuevas API sin romper las API existentes.

Puede encontrar una discusión más extensa aquí: Disección de bibliotecas compartidas

61
miguel.de.icaza

Las bibliotecas compartidas deben versionarse de acuerdo con el siguiente esquema:

blah.so.X.Y.Z

dónde

  • X = versión ABI incompatible con versiones anteriores
  • Y = versión ABI compatible con versiones anteriores
  • Z = Solo cambios internos: sin cambios en la ABI

Por lo general, solo ve el primer dígito como hello.so.1 Porque el primer dígito es lo único que se necesita para identificar la "versión" de la biblioteca, ya que todos los demás dígitos son compatibles con versiones anteriores.

ldconfig mantiene una tabla de las bibliotecas compartidas disponibles en un sistema y dónde existe la ruta a esa biblioteca. Puede verificar esto ejecutando:

ldconfig -p

Cuando se crea un paquete para algo como Red Hat, las bibliotecas compartidas que se llaman en el binario se buscarán y agregarán como dependencias del paquete en el momento de la compilación de RPM. Por lo tanto, cuando vaya a instalar el paquete, el instalador buscará si hello.so.1 Está instalado o no en el sistema marcando ldconfig.

Puede ver las dependencias de un paquete haciendo algo como:

rpm -qpR hello.rpm

Este sistema (a diferencia de Windows) permite que se instalen varias versiones de hello.so En un sistema y que sean utilizadas por diferentes aplicaciones al mismo tiempo.

25
ascotan

libNAME.so es el nombre de archivo utilizado por el compilador/enlazador cuando busca por primera vez una biblioteca especificada por -lNAME. Dentro de un archivo de biblioteca compartida hay un campo llamado SONAME. Este campo se establece cuando la biblioteca misma se vincula por primera vez a un objeto compartido (así) mediante el proceso de compilación. Este SONAME es en realidad lo que un vinculador almacena en un ejecutable dependiendo de que el objeto compartido esté vinculado con él. Normalmente, el SONAME tiene la forma de libNAME.so.MAJOR y se cambia cada vez que la biblioteca se vuelve incompatible con los ejecutables existentes vinculados a él y ambas versiones principales de la biblioteca se pueden mantener instaladas según sea necesario (aunque solo se señalará una para el desarrollo como libNAME.so) Además, para admitir la actualización fácil entre versiones menores de una biblioteca, libNAME.so.MAJOR normalmente es un enlace a un archivo como libNAME.so.MAJOR.MINOR. Se puede instalar una nueva versión secundaria y una vez completada, el enlace a la versión secundaria anterior se abre para señalar a la nueva versión secundaria que actualiza inmediatamente todas las nuevas ejecuciones para usar la biblioteca actualizada. Además, vea mi respuesta a Linux, GNU GCC, ld, scripts de versión y el formato binario ELF - ¿Cómo funciona?

20
penguin359