A resposta direta (talvez óbvia) é que o caminho de pesquisa das bibliotecas que você está vendo com ldd
não inclui os diretórios onde as dependências da biblioteca estão localizadas. Normalmente, a menos que as dependências de uma biblioteca sejam encontradas em locais padrão do sistema, a biblioteca deve ter sido criada com um caminho de execução especificado (usando a variável de ambiente $LD_RUN_PATH
ou a opção de vinculador apropriada). Caso contrário, as bibliotecas não serão encontradas mais tarde em tempo de execução, como você encontrou com ldd
.
Então, por que o Thunderbird funciona mesmo assim, apesar desse "problema"?
Existem algumas maneiras pelas quais as bibliotecas necessárias podem ser encontradas de qualquer maneira, apesar do caminho de execução ausente:
- A variável de ambiente
$LD_LIBRARY_PATH
é configurada no tempo de execução e fornece uma lista de diretórios adicionais para pesquisa. - O diretório necessário pode ter sido incluído no caminho de pesquisa porque foi encontrado no caminho de execução de alguma outra biblioteca não relacionada que foi carregada antes da atual. By the way, eu não tenho certeza se isso funciona como um acidente de implementação de se o padrão especifica isso. De um jeito ou de outro, é frágil porque depende crucialmente da ordem exata na qual as bibliotecas são carregadas.
- A biblioteca pode ter sido carregada manualmente pelo aplicativo usando a função
dlopen()
com um nome de caminho completo.
O Thunderbird parece estar usando a última dessas técnicas. Eu olhei para strace
output do que ele faz na inicialização e parece fazer isso:
- Localize o diretório de onde vem seu próprio binário. Isso é sempre possível porque o assistente de script de shell que inicia o Thunderbird faz isso com um nome de caminho completo.
- Abra o arquivo de texto
dependentlibs.list
encontrado nesse diretório. - Para cada nome de arquivo neste arquivo de texto, na ordem, prefixar o mesmo diretório para formar um nome de caminho completo e carregue-o como uma biblioteca usando
dlopen()
. - Agora, todas as bibliotecas dependentes como
libldap60.so
que você mencionou são "pré-carregadas" e outras bibliotecas que precisam delas não precisam encontrá-las novamente.
Observe que o pedido ou os arquivos listados em dependentlibs.list
são significativos.
A razão pela qual o Thunderbird faz isso é para que o diretório onde ele está localizado não precise ser codificado no aplicativo ou no caminho de execução de qualquer uma de suas bibliotecas internas.
Eu não sei o que o Java faz, mas sem dúvida é algo similar.