¿Existe una ruta de acceso para bibliotecas vinculadas dinámicamente?

¿Existe una ruta de acceso para bibliotecas vinculadas dinámicamente?

Entonces, el proyecto en el que estoy trabajando usa un directorio que no es del sistema para guardar algunas DLL que usa el código. No quiero colocarlos en directorios del sistema, por lo que los ejecutables tienen un rpath configurado para encontrar las DLL. Sin embargo, a medida que se agregan más y más bibliotecas, ahora hay DLL que dependen de otras DLL en ese directorio.

Esas bibliotecas no pueden encontrar las DLL de las que dependen, ya que no están ubicadas en un directorio que el vinculador esté buscando, por ejemplo, un directorio del sistema.

¿Hay alguna manera de hacer que las DLL busquen en este directorio específico que no pertenece al sistema? ¿Como un rpath? ¿Y cómo se hace eso con una biblioteca? El sistema de compilación que se utiliza para el proyecto es CMake, si eso ayuda en la respuesta.

Esta respuesta no funciona porque no hay ninguna etiqueta rPath en la biblioteca:https://unix.stackexchange.com/a/272286/4193

He considerado usar LD_LIBRARY_PATH, y funciona, pero es molesto escribir y no es tan bueno lograr que otras personas usen la aplicación. Si hay una manera de agregar la rPathetiqueta a la biblioteca, esa sería la mejor opción.

Se agradecen sugerencias sobre preguntas y respuestas relevantes anteriores.

Respuesta1

¿Existe una ruta de acceso para bibliotecas vinculadas dinámicamente?

Sí hay. Puede usarlo -Wl,-rpathcon objetos compartidos de ELF al igual que con los ejecutables de ELF. Clonar un pequeño ejemplo que puse aquí:

git clone https://gist.github.com/ardrabczyk/6aeb8545c9b754d6b15be390af4bdff0

Ejecute makepara compilar. Compruebe qué bibliotecas necesita el main ejecutable ELF:

$ readelf -d ./main

Dynamic section at offset 0xe30 contains 22 entries:
  Tag        Type                         Name/Value
 0x0000000000000001 (NEEDED)             Shared library: [libtwo.so]
 0x0000000000000001 (NEEDED)             Shared library: [libc.so.6]
 0x000000000000000f (RPATH)              Library rpath: [.]
(...)

Y compruebe qué bibliotecas son necesarias para libtwo.so:

$ readelf -d ./libtwo.so

Dynamic section at offset 0xe38 contains 22 entries:
  Tag        Type                         Name/Value
 0x0000000000000001 (NEEDED)             Shared library: [libone.so]
 0x0000000000000001 (NEEDED)             Shared library: [libc.so.6]
 0x000000000000000f (RPATH)              Library rpath: [libs]
 (...)

Como puede ver, ambos mainnecesitan libtwo.soalgunos objetos compartidos y ambos tienen rpath configurado. No es necesario configurar LD_LIBRARY_PATH para ejecutar ./main:

$ ./main
I'm in bar()

main siempre buscará su dependencia libtwo.so en .ese directorio actual y libtwo.so a su vez siempre buscará su dependencia libone.so en libsel directorio. Si libsfalta ./main no se iniciará:

$ mv libs libs.bak
$ ./main
./main: error while loading shared libraries: libone.so: cannot open shared object file: No such file or directory

Restaurarlo:

$ mv libs.bak libs
$ ./main
I'm in bar()

Respuesta2

Como no quieres considerarlo como parte del sistema, úsalo como es; una aplicación de usuario!

Si agrega ~/.local/lib/a su LD_LIBRARY_PATH, puede poner todo allí. Simplemente cree una estructura FHS parcial en ~/.local/me gustapapelera,etc.,bibliotecaycompartir. De esa manera no es necesario llamar al programa con una variable de entorno anterior. Todos los demás sistemas simplemente necesitarían agregar a este directorio su variable de entorno de ruta de biblioteca. Muy ordenado y unixish.

Si rechazas también esta solución, sólo queda una posibilidad. O utiliza una ruta fija, que se espera en cada sistema, o una variable de entorno, que contiene una ruta y también se espera.

información relacionada