Bibliotecas compartidas: ldd, ldconfig, LD_LIBRARY_PATH

Bibliotecas dinámicas y estáticas

En Linux, el código reutilizable se distribuye como bibliotecas. Las bibliotecas estáticas (.a) se enlazan al compilar el programa: el código de la biblioteca queda incorporado en el ejecutable. Las bibliotecas dinámicas o compartidas (.so, shared object) se cargan en memoria en tiempo de ejecución y pueden ser compartidas por múltiples programas simultáneamente, ahorrando memoria y facilitando las actualizaciones de seguridad sin recompilar las aplicaciones.

ldd — Listar dependencias de un binario

ldd muestra las bibliotecas compartidas que necesita un ejecutable y dónde las encuentra el cargador dinámico.


$ ldd /bin/bash
        linux-vdso.so.1 (0x00007ffd3e9d6000)
        libtinfo.so.6 => /lib/x86_64-linux-gnu/libtinfo.so.6
        libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6
        /lib64/ld-linux-x86-64.so.2 (0x00007f8b1234a000)
          
  • => → ruta donde se ha encontrado la biblioteca
  • not found → biblioteca no disponible en el sistema

$ ldd /usr/sbin/nginx            # dependencias de nginx
$ ldd /usr/bin/python3
          

ldconfig y /etc/ld.so.conf — El cargador dinámico

El cargador dinámico (ld.so / ld-linux.so) busca las bibliotecas en rutas predefinidas. La configuración de esas rutas se hace en:

  • /etc/ld.so.conf → lista de directorios adicionales
  • /etc/ld.so.conf.d/*.conf → ficheros adicionales incluidos por el anterior
  • /etc/ld.so.cache → caché binaria generada por ldconfig

Añadir una ruta personalizada de bibliotecas:


# echo "/usr/local/lib/miapp" > /etc/ld.so.conf.d/miapp.conf
# ldconfig                       # regenerar la caché
          

Comprobar qué bibliotecas están en caché:


$ ldconfig -p                    # listar todas las bibliotecas en caché
$ ldconfig -p | grep libssl      # filtrar por nombre
          

Siempre que instales una biblioteca en un directorio no estándar debes ejecutar ldconfig para que los programas puedan encontrarla.

LD_LIBRARY_PATH y LD_PRELOAD

LD_LIBRARY_PATH

Variable de entorno que añade directorios de búsqueda de bibliotecas con mayor prioridad que los de /etc/ld.so.conf. Útil para pruebas o entornos de desarrollo.


$ export LD_LIBRARY_PATH=/usr/local/lib/miapp:$LD_LIBRARY_PATH
$ ./mi-programa                  # usa primero las bibliotecas de la ruta añadida

# Uso puntual sin modificar el entorno permanente:
$ LD_LIBRARY_PATH=/tmp/libs ./mi-programa
          

No uses LD_LIBRARY_PATH permanentemente en producción; es una fuente de problemas difíciles de depurar. Usa /etc/ld.so.conf.d/ + ldconfig en su lugar.

LD_PRELOAD

Fuerza la carga de una biblioteca antes que cualquier otra, incluyendo las del sistema. Útil para sustituir funciones puntualmente.


$ LD_PRELOAD=/usr/lib/x86_64-linux-gnu/libfakeroot/libfakeroot-tcp.so fakeroot
          

Ejemplo práctico completo

Compilar una biblioteca y registrarla en el sistema:


# 1. Compilar la biblioteca compartida
$ gcc -shared -fPIC -o libhola.so hola.c

# 2. Copiarla al directorio de bibliotecas del sistema
# cp libhola.so /usr/local/lib/

# 3. Registrar el directorio en el cargador dinámico
# echo "/usr/local/lib" > /etc/ld.so.conf.d/local.conf
# ldconfig

# 4. Verificar que está disponible
$ ldconfig -p | grep libhola
        libhola.so => /usr/local/lib/libhola.so

# 5. Compilar y ejecutar un programa que la use
$ gcc -o programa main.c -lhola
$ ldd ./programa | grep libhola
        libhola.so => /usr/local/lib/libhola.so
          

Las rutas de búsqueda estándar (/lib, /usr/lib, /usr/local/lib) ya están incluidas; solo necesitas configurar /etc/ld.so.conf.d/ para rutas personalizadas.

Instalación desde código fuente y creación de paquetes

Índice de la sección

Índice del curso