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_PATH
e 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 rPath
tag à 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,-rpath
com 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 make
para 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 main
precisam libtwo.so
de 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 libs
diretório. Se libs
estiver 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.