¿Cómo se especifica la ubicación de las bibliotecas a un binario? (linux)

34

Para esta pregunta, usaré un ejemplo específico, pero realmente esto se generaliza a casi cualquier binario en Linux que parece no poder encontrar sus bibliotecas dependientes. Entonces, tengo un programa que no se ejecutará debido a la falta de bibliotecas:

./cart5: error while loading shared libraries: libcorona-1.0.2.so: cannot open shared object file: No such file or directory

ldd arroja algo de luz sobre el tema:

linux-vdso.so.1 =>  (0x00007fff18b01000)
libcorona-1.0.2.so => not found
libstdc++.so.6 => /usr/lib/gcc/x86_64-pc-linux-gnu/4.4.3/libstdc++.so.6 (0x00007f0975830000)
libm.so.6 => /lib/libm.so.6 (0x00007f09755af000)
libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x00007f0975399000)
libc.so.6 => /lib/libc.so.6 (0x00007f0975040000)
libz.so.1 => /lib/libz.so.1 (0x00007f0974e2b000)
/lib64/ld-linux-x86-64.so.2 (0x00007f0975b36000)

Sin embargo, la corona está instalada:

oliver@human$ find / -name libcorona-1.0.2.so 2> /dev/null

/usr/local/lib64/libcorona-1.0.2.so
/home/oliver/installed/corona-1.0.2/src/.libs/libcorona-1.0.2.so

¿Cómo le digo al binario dónde buscar la biblioteca "faltante"?

Mala
fuente

Respuestas:

43

Para una vez, configure la variable LD_LIBRARY_PATHen una lista de directorios separados por dos puntos para buscar. Esto es análogo a los PATHejecutables, excepto que los directorios del sistema estándar se buscan adicionalmente después de los especificados a través del entorno.

LD_LIBRARY_PATH=/usr/local/lib64 ./cart5

Si tiene un programa que mantiene las bibliotecas en una ubicación no estándar y no puede encontrarlas por sí solo, puede escribir un script de contenedor:

#!/bin/sh
if [ -n "$LD_LIBRARY_PATH" ]; then
  LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib64
else
  LD_LIBRARY_PATH=/usr/local/lib64
fi
export LD_LIBRARY_PATH
exec /path/to/cart5 "$@"

La lista de directorios del sistema estándar se mantiene en /etc/ld.so.conf. Los sistemas recientes permiten que este archivo incluya otros archivos; si el suyo contiene algo como include /etc/ld.so.conf.d/*.conf, cree un nuevo archivo llamado que /etc/ld.so.conf.d/mala.confcontenga los directorios que desea agregar. Después de cambiar /etc/ld.so.confo un archivo incluido, ejecute /sbin/ldconfigpara que los cambios surtan efecto (esto actualiza un caché).

( LD_LIBRARY_PATHtambién se aplica a muchas otras unidades, incluidas FreeBSD, NetBSD, OpenBSD, Solaris y Tru64. HP-UX tiene SHLIB_PATHy Mac OS X tiene DYLD_LIBRARY_PATH. /etc/ld.so.conftiene análogos en la mayoría de las unidades, pero la ubicación y la sintaxis difieren más ampliamente).

Gilles 'SO- deja de ser malvado'
fuente
1
Fantástico, muchas gracias. No tenía idea sobre /etc/ld.so.conf, y será muy útil para mí en el futuro.
Mala
15

Si desea evitar LD_LIBRARY_PATH, también puede hacerlo durante el enlace:

gcc -o exename -L/path/to/dynamiclib/ -lnameofLib \
    -Wl,-R/path/to/dynamiclib/ sourceCode1.c ...

El -Wl, ... se usa para pasar comandos adicionales al enlazador, y en este caso, con -R le dice al enlazador que almacene esta ruta como la "ruta de búsqueda predeterminada" para el .so.

Mantengo notas de muchos pequeños consejos como este, en mi sitio:

https://www.thanassis.space/tricks.html

ttsiodras
fuente
Pero si la biblioteca en cuestión en sí misma ha compartido bibliotecas para buscar, la ruta almacenada en el binario no se aplica de forma recursiva a las búsquedas de la subbiblioteca. No he encontrado una manera de evitar esto aparte de configurar LD_LIBRARY_PATH en el entorno, que luego se aplica a las búsquedas recursivas ...
Ethan
@ Ethan: cierto. Pero lo que también es cierto es que los escenarios habituales en los que desea "empaquetar" bibliotecas compartidas para algunos archivos binarios, es uno donde los coloca todos juntos; por ejemplo /opt/mypackage/bin/someBinary, necesitará bibliotecas en las que almacene /opt/mypackage/lib/. Casi todos los SW propietarios instalados bajo / opt siguen esta regla, lo que significa que la forma que se muestra arriba cubrirá todas esas instalaciones. Por lo general, también agregarán un enlace simbólico debajo de / usr / bin que apunta al binario debajo de / opt, sabiendo que la "ruta de búsqueda predeterminada" encontrará los .sos en la /opt/.../libcarpeta correspondiente .
ttsiodras
sí, en mi caso, quería probar un paquete al vincularlo con su directorio de compilación en lugar de instalarlo ... (pero el paquete tenía varios .so internos con algunas interdependencias ... variedad de soluciones alternativas pero simplemente molesto)
Ethan
0

Esto indica que libcorona no está instalado en la ruta correcta. Mueva el directorio libcorona a la ruta correcta, el problema se resolverá.

Rathi
fuente
¿Cómo es esto mejor que otras respuestas?
Toto
@Toto a diferencia de las otras respuestas, básicamente está instalando manualmente los archivos ... Aunque eso no significa exactamente que esta respuesta sea mejor, pero ES una opción que debe considerarse (las personas también hacen esto en Windows copiando bibliotecas en system32 / sysWOW64 cuando sus aplicaciones no pueden encontrarlas), no es que sea recomendable, porque se desaconseja encarecidamente.
Tcll