Bibliotecas estáticas y compartidas Linux - LPI 101

Las funciones que a menudo se utilizan se archivan como bibliotecas. Durante la compilación, estas bibliotecas se pueden vincular al código que utiliza las llamadas a la función de biblioteca. La biblioteca se puede enlazar estáticamente o dinámicamente al código.

El compilador gcc puede vincular bibliotecas en una variedad de formas (muchas opciones). Sin embargo, de forma predeterminada, enlazará los archivos que se proporcionan en la línea de comandos que no tienen una extensión .c (sólo los archivos .c se tratan como código).

Listado 1: Vinculación por defecto

Esto producirá un ejecutable a.out con el objeto Hello.o estáticamente vinculado a él.

Ilustración de una aplicación vinculada estáticamente (a.out):

Bibliotecas estáticas

Las bibliotecas estáticas son archivos .o archivados. Estos archivos se crean con la herramienta ar y tienen una extensión .a .

Listado2: agregar un archivo de objeto a un archivo:

Bibliotecas dinámicas/compartidas

Una biblioteca compartida es una biblioteca que será cargada por el programa cuando se ejecuta. También se dice que la biblioteca está cargada dinámicamente.

Listado 3: Creación de una biblioteca compartida:

El indicador -fPIC habilita la generación de código independiente de posición.

Listado4: Compilación con una biblioteca compartida:

Esto producirá un ejecutable a.out. Sin embargo, si intenta ejecutar esto, se quejará con el mensaje de error que se muestra a continuación.

Ilustración de una aplicación vinculada dinámicamente (a.out):

El proceso de adjuntar una biblioteca dinámica en tiempo de ejecución se llama vinculación y es manejado por la biblioteca ld.so. ¿Cómo sabe el enlazador dónde encontrar libfoo.so?

Error de biblioteca compartida no encontrada:

Este error ilustra el caso en el que el vinculador no pudo encontrar la biblioteca dinámica libfoo.so.1.0. En la siguiente sección veremos qué se puede hacer para solucionar este problema.

Nomenclatura de la biblioteca compartida y carga dinámica
Usaremos el ejemplo anterior para entender cómo se mantienen las bibliotecas de Linux.

Figura 1: Los nombres de la biblioteca compartida
Para averiguar qué bibliotecas compartidas necesita un ejecutable en tiempo de ejecución, se utiliza la herramienta ldd.

Ejemplo:

Tenga en cuenta que libfoo.so.1.0 no se encuentra. Esto se debe a que el a.out necesita cargar dinámicamente esta biblioteca y el enlazador dinámico ld.so no tiene conocimiento de esta nueva biblioteca.

De hecho, el enlazador utiliza una base de datos denominada ldcache que contiene entradas del formulario:

  • soname =>/path/to/library

El contenido de ld-cache se puede ver con el siguiente comando:

La ld-cache se genera en el arranque por la misma herramienta ldconfig. De forma predeterminada, ldconfig explorará los directorios /lib y /usr/lib para crear el ld-cache.
Si las bibliotecas están instaladas en diferentes ubicaciones (por ejemplo, /usr/local/lib, /opt/lib o /usr/X11R6/lib), estos directorios deben ser listados en /etc/ld.so.conf permitiendo que ldconfig lleve estos directorios a Consideración al construir la caché.

¿Qué sucede cuando se inicia una aplicación?

La aplicación pedirá al enlazador para las bibliotecas dinámicas que necesita usar un soname, el enlazador luego consultará el ld-cache y asociará este nombre con la ruta completa a la biblioteca real. Una vez que se conoce la ruta completa, el vinculador puede vincular la biblioteca con la aplicación.

¿Qué sucede si el ld-cache no contiene la ruta completa a la biblioteca?

En general, la aplicación no se iniciará y se imprimirá un mensaje de error diciendo "no se puede abrir archivo de objeto compartido: No existe tal archivo o directorio". Pero también se puede definir una variable global llamada LD_LIBRARY_PATH y asignar a esta variable el nombre del directorio que contiene la biblioteca.

Sabiendo esto, ahora podemos solucionar el problema con nuestra aplicación anterior usando uno de los dos métodos siguientes:

1. Si el binario necesita ser probado temporalmente, defina la variable LD_LIBRARY_PATH como sigue:

2. Si es root y desea que la biblioteca esté disponible para todos, copie el archivo libfoo.so.1.0 en /usr/local/lib/ y ejecute ldconfig para actualizar el caché ld. 

La especificación GNU aconseja que las bibliotecas se almacenen en /usr/local/lib. Estas directrices son seguidas por los desarrolladores y la mayoría del código tarballed instalará las bibliotecas en ese directorio y los binarios en /usr/local/bin. Instalar y quitar este código del sistema sería hecho por ¨make install "y"make uninstall".

El FHS (Filesystem Hierarchy Standard) recomienda que las bibliotecas se mantengan en /usr/lib/ y los binarios asociados en /usr/bin/. Este estándar de la convención es respetado por las distribuciones de Linux. En efecto, el código maduro y estable se almacena en /usr/ en lugar de /usr/local/ y las dos normas no conducen a ninguna contradicción. La instalación y eliminación de este código de código se haría utilizando el comando rpm.

Nota: Con ciertas distribuciones el directorio /usr/local/lib/ no es escaneado por ldconfig. Es simplemente una cuestión de agregar este directorio a /etc/ld.so.conf y ... reiniciar?

Publicar un comentario

0 Comentarios