Cargar objetos compartidos en relación con la ruta ejecutable

Cargar objetos compartidos en relación con la ruta ejecutable

Estoy intentando que una aplicación C cargue objetos compartidos desde un directorio relativo, independientemente de dónde lo llame. Hasta ahora sólo funciona si estoy en el mismo directorio que el ejecutable cuando lo llamo:

~/prog$ ./my_program
Success
~/prog$ cd ..
~$ ./prog/my_program
./prog/my_program: error while loading shared libraries: libs/libmysharedobject.so: cannot open shared object file: No such file or directory

Como puede adivinar por el resultado anterior, el objeto compartido se almacena en el ~/prog/libs/directorio. Así es como se ven las llamadas gcc relevantes:

gcc -std=c99 -ggdb -Wall -pedantic -Isrc
    -fPIC -shared -Wl,-soname,libs/libmysharedogbject.so
    -o libs/libmysharedobject.so libs/mysharedobject.c
[...]
gcc [CFLAGS omitted] -o my_program main.c
    build/src/my_program.o build/src/common.o
    -lm -Llibs -lmysharedobject

Aquí está la parte superior del resultado de readelf -d my_program:

Dynamic section at offset 0x6660 contains 26 entries:
  Tag        Type                         Name/Value
 0x0000000000000001 (NEEDED)             Shared library: [libm.so.6]
 0x0000000000000001 (NEEDED)             Shared library: [libs/libmysharedobject.so]
 0x0000000000000001 (NEEDED)             Shared library: [libc.so.6]

Intenté agregar -Wl,-z,origin,-rpath='$ORIGIN', lo que hace que aparezcan las siguientes líneas en readelfel resultado de :

 0x000000000000000f (RPATH)              Library rpath: [$ORIGIN]
[...]
 0x000000006ffffffb (FLAGS_1)            Flags: ORIGIN

Pero no parece resolver mi problema. También intenté configurar rpathen $ORIGIN/libs, .y ./libs, todo sin éxito. (ACTUALIZACIÓN: $(CURDIR)tampoco tiene ningún efecto. Esto me sorprende, ya que se expandió a una ruta absoluta).

¿Hay alguna manera de hacer que mi ejecutable encuentre sus objetos compartidos independientemente del directorio desde el que se invoque, preferiblemente sin que el usuario final lo configure LD_LIBRARY_PATHcada vez? ¿O estoy intentando hacer algo que Linux no admite?

Respuesta1

Establezca rpath en $ORIGIN/libs y establezca soname en libsharedobject en lugar de libs/libsharedobject. Mi archivo MAKE es el siguiente.

all: my_program

libs/libmysharedobject.so: Makefile success.c
  gcc -fPIC -shared -Wl,-soname,libmysharedobject.so \
    -o libs/libmysharedobject.so success.c

my_program: Makefile libs/libmysharedobject.so
  gcc -o my_program main.c -Llibs -lmysharedobject -Wl,-R,'$$ORIGIN/libs'

información relacionada