serie - error while loading shared libraries linux
¿Cuál es la diferencia entre LD_LIBRARY_PATH y-L en el momento del enlace? (5)
Al revisar el hombre para g ++, descubrí que la opción -lxxxxx
está buscando libxxxxx.a
en la ruta provista -L
así que en el momento de vinculación, solo se cargará el archivo .a
. En el tiempo de ejecución, si falta una biblioteca, solo se cargará la biblioteca como objeto compartido, así que .so se cargará y luego se verá en LD_LIBRARY_PATH
. En el ejecutable en el que estoy trabajando, veo que en algún directorio de la biblioteca, existe la versión libxxxx.a
y libxxxx.so
así que creo que significa que la biblioteca se puede vincular en el momento de la vinculación o vincular en el tiempo de ejecución como un objeto compartido.
Si una biblioteca solo existe como objeto compartido, significa que la ruta del directorio de la biblioteca debe ser LD_LIBRARY_PATH
para que se encuentre en el tiempo de ejecución. Si una biblioteca existe solo como un archivo archivado .a, entonces significa que debe estar vinculada en la compilación del ejecutable y luego -L directorypath y -lxxxxx
deben proporcionarse en g ++ en el momento de la compilación.
Este es mi entendimiento ... y al menos está en línea con tus observaciones
Tengo problemas con LD_LIBRARY_PATH
en el momento del enlace (esta pregunta no tiene nada que ver con el tiempo de ejecución).
La línea de enlace tiene este aspecto cuando ejecuto make (este es un sistema Linux que usa g ++ versión 4.1.x):
g++ a.o b.o c.o -o myapp /
-L/long/path/to/libs/ /
-L/another/long/path/ /
-labc -ldef -lghi
Las opciones -l
referencia a las bibliotecas compartidas (por ejemplo, libabc.so) que existen en los directorios especificados por las opciones -L
. Esos directorios también aparecen en LD_LIBRARY_PATH
. Con esa configuración, el enlace es exitoso y puedo ejecutar la aplicación.
Si elimino los directorios de LD_LIBRARY_PATH
, obtengo una única línea de error como:
/usr/bin/ld: cannot find -labc
Por otro lado, si elimino los directorios de la lista de opciones -L
, recibo muchas advertencias como:
/usr/bin/ld: warning: libabc.so, needed by /long/path/to/libs/libxyz.so,
not found (try using -rpath or -rpath-link)
y luego muchos más errores, tales como:
/long/path/to/libs/libdef.so: undefined reference to `Foo::Bar<Baz>::junk(Fred*)''
¿Alguien puede explicar la diferencia entre LD_LIBRARY_PATH
y -L
? Me gustaría entender esto en profundidad, por lo que las referencias son muy apreciadas.
Además, ¿qué debo agregar a la línea de enlace para evitar el uso de LD_LIBRARY_PATH
?
EDITAR: Cuando faltaban los directorios de -L
, el compilador sugirió "intentar usar -rpath o -rpath-link". No creo que haya visto esas opciones en un makefile antes. ¿Tienes? Aunque no estoy seguro de si eso ayudaría al problema LD_LIBRARY_PATH
.
Hay dos respuestas a esta pregunta, parte de la respuesta se encuentra en el enlace en tiempo de compilación (es decir, gcc -lfoo -L/usr/lib
... que a su vez llama a ld
), y en las búsquedas del enlazador en tiempo de ejecución.
Cuando compila su programa, el compilador comprueba la sintaxis y luego el vinculador garantiza que los símbolos necesarios para la ejecución existen (es decir, variables / métodos / etc), entre otras cosas. LD_LIBRARY_PATH
, como se ha señalado, tiene el efecto secundario de alterar la forma en que se comportan gcc
/ ld
, así como la forma en que se comporta el enlazador en tiempo de ejecución al modificar la ruta de búsqueda.
Cuando ejecuta su programa, el vinculador en tiempo de ejecución realmente busca las bibliotecas compartidas (en el disco o desde la memoria si es posible), y carga los símbolos / código / etc. compartidos. Nuevamente, LD_LIBRARY_PATH
afecta implícitamente esta ruta de búsqueda (a veces no es una buena opción) cosa, como se ha mencionado.)
La solución correcta para esto sin usar LD_LIBRARY_PATH
en la mayoría de los sistemas Linux es agregar la ruta que contiene sus bibliotecas compartidas a /etc/ld.so.conf
(o en algunas distribuciones, cree un archivo en /etc/ld.so.conf.d/
con la ruta en ella) y ejecute ldconfig
( /sbin/ldconfig
como root) para actualizar el caché de enlaces del vinculador de tiempo de ejecución.
Ejemplo en Debian:
jewart@dorfl:~$ cat /etc/ld.so.conf.d/usrlocal.conf
/usr/local/lib
Luego, cuando se ejecuta el programa, el enlazador en tiempo de ejecución buscará en esos directorios las bibliotecas a las que se ha vinculado su binario.
Si desea saber qué bibliotecas conoce el vinculador de tiempo de ejecución, puede utilizar:
jewart@dorfl:~$ ldconfig -v
/usr/lib:
libbfd-2.18.0.20080103.so -> libbfd-2.18.0.20080103.so
libkdb5.so.4 -> libkdb5.so.4.0
libXext.so.6 -> libXext.so.6.4.0
Y, si desea saber a qué bibliotecas está vinculado un binario, puede usar ldd
como tal, que le dirá qué biblioteca va a elegir su vinculador de tiempo de ejecución:
jewart@dorfl:~$ ldd /bin/ls
linux-vdso.so.1 => (0x00007fffda1ff000)
librt.so.1 => /lib/librt.so.1 (0x00007f5d2149b000)
libselinux.so.1 => /lib/libselinux.so.1 (0x00007f5d2127f000)
libacl.so.1 => /lib/libacl.so.1 (0x00007f5d21077000)
libc.so.6 => /lib/libc.so.6 (0x00007f5d20d23000)
La configuración de LD_LIBRARY_PATH
tiene la mayor prioridad, por lo que cuando se establece, el conjunto de directorios mencionado por LD_LIBRARY_PATH
se busca primero incluso antes del conjunto estándar
de directorios. Así que en su caso, la configuración de LD_LIBRARY_PATH
está influenciando la búsqueda de
Las bibliotecas mencionadas con la opción -l
. Sin LD_LIBRARY_PATH
algunas de las dependencias
podría haber sido resuelto desde el conjunto estándar de directorios.
Aunque la configuración de LD_LIBRARY_PATH
ayuda con la depuración y para probar una versión más nueva de
una biblioteca, su uso en la configuración e implementación del entorno de desarrollo general se considera mala.
Consulte también este CÓMO de la documentación de Linux para obtener más detalles sobre las bibliotecas compartidas
Si tuviera que adivinar, diría que el vinculador está recurriendo al uso de LD_LIBRARY_PATH
para resolver las bibliotecas a las que están vinculados dinámicamente sus enlaces directos (por ejemplo, libabc.so
, libdef.so
y libghi.so
). Al mirar la página de manual de ld
, parece que se vincula con un .so
que fue creado usando -rpath
afectaría la forma en que funciona la búsqueda de símbolos enlazados dinámicamente.
LD_LIBRARY_PATH
está diseñado para encontrar bibliotecas compartidas cuando se ejecuta una aplicación. Es un efecto secundario que está afectando su enlace, y no debe confiar en eso.
Como un efecto secundario a menudo no deseado, LD_LIBRARY_PATH también se buscará en la etapa de enlace (ld) después de los directorios especificados con -L (también si no se proporciona el distintivo -L).