Existe um rpath para bibliotecas vinculadas dinâmicas?

Existe um rpath para bibliotecas vinculadas dinâmicas?

Portanto, o projeto no qual estou trabalhando usa um diretório que não é do sistema para manter algumas DLLs que o código usa. Não quero colocá-los nos diretórios do sistema, portanto os executáveis ​​​​têm um rpath definido para localizar as DLLs. No entanto, à medida que mais e mais bibliotecas são adicionadas, agora existem DLLs que dependem de outras DLLs nesse diretório.

Essas bibliotecas não conseguem encontrar as DLLs das quais dependem, pois não estão localizadas no diretório que o vinculador está procurando, por exemplo, um diretório do sistema.

Existe uma maneira de fazer com que as DLLs pesquisem esse diretório específico que não seja do sistema? Como um rpath? E como isso é feito com uma biblioteca? O sistema de compilação usado para o projeto é o CMake, se isso ajudar na resposta.

Esta resposta não funciona, pois não há tag rPath na biblioteca:https://unix.stackexchange.com/a/272286/4193

Pensei em usar LD_LIBRARY_PATHe funciona, mas é chato digitar e não é tão bom fazer com que outras pessoas usem o aplicativo. Se houver uma maneira de adicionar a rPathtag à biblioteca, essa seria a melhor opção.

Indicações para perguntas e respostas relevantes anteriores são apreciadas.

Responder1

Existe um rpath para bibliotecas vinculadas dinâmicas?

Sim existe. Você pode usar -Wl,-rpathcom objetos compartilhados ELF da mesma forma que com executáveis ​​ELF. Clone um pequeno exemplo que coloquei aqui:

git clone https://gist.github.com/ardrabczyk/6aeb8545c9b754d6b15be390af4bdff0

Execute makepara compilar. Verifique quais bibliotecas são necessárias para o main executável ELF:

$ readelf -d ./main

Dynamic section at offset 0xe30 contains 22 entries:
  Tag        Type                         Name/Value
 0x0000000000000001 (NEEDED)             Shared library: [libtwo.so]
 0x0000000000000001 (NEEDED)             Shared library: [libc.so.6]
 0x000000000000000f (RPATH)              Library rpath: [.]
(...)

E verifique quais bibliotecas são necessárias libtwo.so:

$ readelf -d ./libtwo.so

Dynamic section at offset 0xe38 contains 22 entries:
  Tag        Type                         Name/Value
 0x0000000000000001 (NEEDED)             Shared library: [libone.so]
 0x0000000000000001 (NEEDED)             Shared library: [libc.so.6]
 0x000000000000000f (RPATH)              Library rpath: [libs]
 (...)

Como você pode ver, ambos mainprecisam libtwo.sode alguns objetos compartilhados e ambos possuem rpath definido. Você não precisa definir LD_LIBRARY_PATH para executar ./main:

$ ./main
I'm in bar()

main sempre procurará sua dependência libtwo.so no .diretório atual e libtwo.so por sua vez sempre procurará sua dependência libone.so no libsdiretório. Se libsestiver faltando ./main não será iniciado:

$ mv libs libs.bak
$ ./main
./main: error while loading shared libraries: libone.so: cannot open shared object file: No such file or directory

Restaure-o:

$ mv libs.bak libs
$ ./main
I'm in bar()

Responder2

Já que você não quer considerá-lo como parte do sistema, use-o como é; um aplicativo de usuário!

Se você adicionar ~/.local/lib/ao seu LD_LIBRARY_PATH, poderá colocar tudo lá. Basta criar uma estrutura parcial da ESF sob ~/.local/o mesmocaixa,etc.,bibliotecaecompartilhar. Dessa forma, você não precisa chamar o programa com uma variável de ambiente anterior. Todos os outros sistemas precisariam apenas anexar a este diretório a variável de ambiente do caminho da biblioteca. Muito arrumado e unixish.

Se você também rejeitar esta solução, resta apenas uma possibilidade. Você usa um caminho fixo, que é esperado em cada sistema, ou uma variável de ambiente, que contém um caminho e também é esperada.

informação relacionada