Загрузить общие объекты относительно пути к исполняемому файлу

Загрузить общие объекты относительно пути к исполняемому файлу

Я пытаюсь заставить приложение C загружать общие объекты из относительного каталога независимо от того, откуда я его вызываю. Пока это работает только если я нахожусь в том же каталоге, что и исполняемый файл, когда я его вызываю:

~/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

Как вы можете догадаться из вывода выше, общий объект хранится в каталоге ~/prog/libs/. Вот как выглядят соответствующие вызовы gcc:

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

Вот верхняя часть вывода 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]

Я попробовал добавить -Wl,-z,origin,-rpath='$ORIGIN', что привело к появлению следующих строк в readelfвыводе :

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

Но это, похоже, не решает мою проблему. Я также пробовал устанавливать rpath, $ORIGIN/libs, .и ./libs, все безрезультатно. (ОБНОВЛЕНИЕ: $(CURDIR)тоже не дает никакого эффекта. Это меня удивляет, так как он расширяется до абсолютного пути.)

Есть ли способ заставить мой исполняемый файл находить свои общие объекты независимо от каталога, из которого он вызывается, желательно без необходимости LD_LIBRARY_PATHкаждый раз устанавливать конечного пользователя? Или я пытаюсь сделать что-то, что Linux не поддерживает?

решение1

Установите rpath на $ORIGIN/libs и установите soname на libsharedobject вместо libs/libsharedobject. Мой makefile выглядит следующим образом.

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'

Связанный контент