Como você especifica o local das bibliotecas para um binário? (linux)


34

Para esta pergunta, usarei um exemplo específico, mas na verdade isso generaliza para praticamente qualquer binário no linux que não consiga encontrar suas 'bibliotecas dependentes. Então, eu tenho um programa que não será executado por falta de bibliotecas:

./cart5: error while loading shared libraries: libcorona-1.0.2.so: cannot open shared object file: No such file or directory

O ldd lança alguma luz sobre o assunto:

linux-vdso.so.1 =>  (0x00007fff18b01000)
libcorona-1.0.2.so => not found
libstdc++.so.6 => /usr/lib/gcc/x86_64-pc-linux-gnu/4.4.3/libstdc++.so.6 (0x00007f0975830000)
libm.so.6 => /lib/libm.so.6 (0x00007f09755af000)
libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x00007f0975399000)
libc.so.6 => /lib/libc.so.6 (0x00007f0975040000)
libz.so.1 => /lib/libz.so.1 (0x00007f0974e2b000)
/lib64/ld-linux-x86-64.so.2 (0x00007f0975b36000)

No entanto, a corona está instalada:

oliver@human$ find / -name libcorona-1.0.2.so 2> /dev/null

/usr/local/lib64/libcorona-1.0.2.so
/home/oliver/installed/corona-1.0.2/src/.libs/libcorona-1.0.2.so

Como digo ao binário onde procurar a biblioteca "ausente"?

Respostas:


43

Para uma única vez, defina a variável LD_LIBRARY_PATHcomo uma lista de diretórios separados por dois pontos a serem pesquisados. Isso é análogo a PATHexecutáveis, exceto que os diretórios padrão do sistema são pesquisados ​​adicionalmente após os especificados pelo ambiente.

LD_LIBRARY_PATH=/usr/local/lib64 ./cart5

Se você possui um programa que mantém as bibliotecas em um local não padrão e não consegue encontrá-las por conta própria, é possível escrever um script de wrapper:

#!/bin/sh
if [ -n "$LD_LIBRARY_PATH" ]; then
  LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib64
else
  LD_LIBRARY_PATH=/usr/local/lib64
fi
export LD_LIBRARY_PATH
exec /path/to/cart5 "$@"

A lista de diretórios padrão do sistema é mantida /etc/ld.so.conf. Sistemas recentes permitem que esse arquivo inclua outros arquivos; se o seu contiver algo como include /etc/ld.so.conf.d/*.conf, crie um novo arquivo chamado /etc/ld.so.conf.d/mala.confcontendo os diretórios que você deseja adicionar. Depois de alterar /etc/ld.so.confou incluir um arquivo, execute /sbin/ldconfigas alterações para que sejam efetivadas (isso atualiza um cache).

( LD_LIBRARY_PATHtambém se aplica a muitos outros departamentos, incluindo FreeBSD, NetBSD, OpenBSD, Solaris e Tru64. O HP-UX possui SHLIB_PATHe o Mac OS X possui DYLD_LIBRARY_PATH. /etc/ld.so.confpossui análogos na maioria dos departamentos, mas a localização e a sintaxe diferem mais amplamente.)


1
Fantástico, muito obrigado. Eu não tinha idéia do /etc/ld.so.conf, e será muito útil para mim no futuro.
Mala

15

Se você deseja evitar LD_LIBRARY_PATH, também pode fazer isso durante o link:

gcc -o exename -L/path/to/dynamiclib/ -lnameofLib \
    -Wl,-R/path/to/dynamiclib/ sourceCode1.c ...

O -Wl, ... é usado para passar comandos extras para o vinculador e, nesse caso, com -R, você solicita ao vinculador que armazene esse caminho como o "caminho de pesquisa padrão" para o .so.

Eu mantenho anotações de muitas dicas pequenas como esta, no meu site:

https://www.thanassis.space/tricks.html


Mas se a biblioteca em questão em si tiver compartilhado bibliotecas para procurar, o rpath armazenado no binário não será aplicado recursivamente às pesquisas da sub-biblioteca. Eu não encontrei uma maneira de contornar este outro do que a criação LD_LIBRARY_PATH no ambiente, o que, em seguida, não são aplicadas para pesquisas recursivas ...
Ethan

@ Ethan: Verdade. Mas o que também é verdade é que os cenários usuais em que você deseja "empacotar" bibliotecas compartilhadas para alguns binários são aqueles em que você os agrupou; por exemplo /opt/mypackage/bin/someBinary, precisará de bibliotecas em que você armazena /opt/mypackage/lib/. Praticamente todos os SW proprietários instalados sob / opt seguem esta regra - o que significa que a maneira mostrada acima abrangerá todas essas instalações. Eles normalmente também adicionam um link simbólico em / usr / bin que aponta para o binário em / opt - sabendo que o "caminho de pesquisa padrão" encontrará os .sos na /opt/.../libpasta apropriada .
Ttsiodras

Sim, no meu caso, eu estava querendo testar um pacote vinculando-o ao diretório de compilação, em vez de instalá-lo ... (mas o pacote tinha vários .so internos com algumas interdependências ... variedade de soluções alternativas, mas apenas irritante)
Ethan

0

Isso indica que a libcorona não está instalada no caminho correto. Mova o diretório libcorona para o caminho correto, o problema será resolvido.


Como isso é melhor do que outras respostas?
Toto #

@ Para diferente das outras respostas, você basicamente instala os arquivos manualmente ... Embora isso não signifique exatamente que essa resposta seja melhor, mas é uma opção que deve ser considerada (as pessoas também fazem isso no Windows, copiando bibliotecas para system32 / sysWOW64 quando seus aplicativos não conseguem encontrá-los), não que seja recomendado, porque é altamente desencorajado.
Tcll 15/06
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.