Estou tentando fazer com que um aplicativo C carregue objetos compartilhados de um diretório relativo, independentemente de onde eu o chamo. Até agora só funciona se eu estiver no mesmo diretório do executável quando o chamo:
~/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 você pode imaginar pela saída acima, o objeto compartilhado é armazenado no ~/prog/libs/
diretório. Esta é a aparência das chamadas relevantes do 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
Aqui está o topo da saída 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]
Eu tentei adicionar -Wl,-z,origin,-rpath='$ORIGIN'
, o que faz com que as seguintes linhas apareçam na readelf
saída de:
0x000000000000000f (RPATH) Library rpath: [$ORIGIN]
[...]
0x000000006ffffffb (FLAGS_1) Flags: ORIGIN
Mas isso não parece resolver meu problema. Eu também tentei configurar rpath
para $ORIGIN/libs
, .
, e ./libs
, tudo sem sucesso. (ATUALIZAÇÃO: $(CURDIR)
também não tem efeito. Isso me surpreende, pois foi expandido para um caminho absoluto.)
Existe uma maneira de fazer com que meu executável encontre seus objetos compartilhados, independentemente do diretório a partir do qual ele é invocado, de preferência sem ter o usuário final configurado LD_LIBRARY_PATH
todas as vezes? Ou estou tentando fazer algo que o Linux não suporta?
Responder1
Defina rpath como $ORIGIN/libs e defina soname como libsharedobject em vez de libs/libsharedobject. Meu makefile é o seguinte.
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'