Entiendo cómo definir incluir objetos compartidos en el momento de la vinculación/compilación. Sin embargo, todavía me pregunto cómo buscan los ejecutables el objeto compartido (*.so
bibliotecas) en tiempo de ejecución.
Por ejemplo, mi aplicación a.out
llama a funciones definidas en lib.so
biblioteca. Después de compilar, muevo lib.so
a un nuevo directorio en mi $HOME
.
¿Cómo puedo decirle a a.out
para ir a buscarlo allí?
Respuesta aceptada:
La biblioteca compartida HOWTO explica la mayoría de los mecanismos involucrados, y el manual del cargador dinámico entra en más detalles. Cada variante de Unix tiene su propia manera, pero la mayoría usa el mismo formato ejecutable (ELF) y tiene enlazadores dinámicos similares¹ (derivados de Solaris). A continuación, resumiré el comportamiento común con un enfoque en Linux; consulte los manuales de su sistema para conocer la historia completa.
(Nota de terminología:la parte del sistema que carga bibliotecas compartidas a menudo se denomina "enlazador dinámico", pero a veces "cargador dinámico" para ser más precisos. "Enlazador dinámico" también puede significar la herramienta que genera instrucciones para el cargador dinámico al compilar un programa, o la combinación de la herramienta de tiempo de compilación y el cargador de tiempo de ejecución. En esta respuesta, "vinculador" se refiere a la parte de tiempo de ejecución).
En pocas palabras, cuando busca una biblioteca dinámica (.so
archivo) el enlazador intenta:
- directorios enumerados en
LD_LIBRARY_PATH
variable de entorno (DYLD_LIBRARY_PATH
en OSX); - directorios enumerados en el rpath del ejecutable;
- directorios en la ruta de búsqueda del sistema, que (al menos en Linux) consta de las entradas en
/etc/ld.so.conf
más/lib
y/usr/lib
.
El rpath se almacena en el ejecutable (es el DT_RPATH
o DT_RUNPATH
atributo dinámico). Puede contener rutas absolutas o rutas que comienzan con $ORIGIN
para indicar una ruta relativa a la ubicación del ejecutable (por ejemplo, si el ejecutable está en /opt/myapp/bin
y su rpath es $ORIGIN/../lib:$ORIGIN/../plugins
entonces el enlazador dinámico buscará en /opt/myapp/lib
y /opt/myapp/plugins
). El rpath normalmente se determina cuando se compila el ejecutable, con el -rpath
opción a ld
, pero puedes cambiarlo después con chrpath
.
En el escenario que describe, si es el desarrollador o empaquetador de la aplicación y tiene la intención de que se instale en un …/bin
, …/lib
estructura, luego enlace con -rpath='$ORIGIN/../lib'
. Si está instalando un binario preconstruido en su sistema, coloque la biblioteca en un directorio en la ruta de búsqueda (/usr/local/lib
si es el administrador del sistema; de lo contrario, un directorio que agregue a $LD_LIBRARY_PATH
), o prueba chrpath
.