Carregar objetos compartilhados em relação ao caminho do executável

1

Estou tentando obter um aplicativo C para carregar objetos compartilhados de um diretório relativo, independentemente de onde eu o chame. Até agora só funciona se eu estiver no mesmo diretório que o executável quando eu o chamar:

~/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 na saída acima, o objeto compartilhado é armazenado no diretório ~/prog/libs/ . Veja como são as 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 saída de readelf :

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

Mas isso não parece resolver o meu problema. Eu também tentei definir rpath para $ORIGIN/libs , . e ./libs , tudo sem sucesso. (UPDATE: $(CURDIR) também não tem nenhum efeito. Isso me surpreende, pois é 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 é chamado, de preferência sem que o usuário final defina LD_LIBRARY_PATH todas as vezes? Ou estou tentando fazer algo que o Linux não suporta?

    
por Fraxtil 17.06.2014 / 01:09

1 resposta

2

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'
    
por 05.07.2015 / 07:39