Я пытаюсь заставить приложение 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'