usr / bin/ ld: incapaz de encontrar-l
estou a tentar compilar o meu programa e ele devolve este erro:
usr/bin/ld: cannot find -l<nameOfTheLibrary>
no meu makefile, uso o comando g++
e o link para a minha biblioteca, que é um link simbólico para a minha biblioteca, localizado num outro directório.
Existe uma opção para adicionar para fazer com que funcione por favor?
12 answers
Se o nome da sua Biblioteca é say libxyz.so
e está localizado no caminho diga:
/home/user/myDir
Então para ligá-lo ao seu programa:
g++ -L/home/user/myDir -lxyz myprog.cpp -o myprog
Por exemplo, encontrei este problema ao tentar compilar o MySQL com o suporte do ZLIB. Eu estava recebendo um erro como este durante a compilação:
/usr/bin/ld: cannot find -lzlib
Eu fiz alguns Googl ing e continuaram a vir em diferentes problemas do mesmo tipo, onde as pessoas diziam para se certificar .assim o arquivo realmente existe e se não, em seguida, crie um link simbólico para o ficheiro com a versão, por exemplo, zlib.então.1.2.8. Mas, quando verifiquei, zlib.so existia. Então, eu pensei, certamente que esse não poderia ser o problema.
Deparei-me com outro post nos Internets que sugeria executar make com LD_DEBUG=tudo:
LD_DEBUG=all make
Apesar de ter recebido uma tonelada de resultados de depuração, não ajudou muito. Acrescentou mais confusão do que qualquer outra coisa. Estava prestes a desistir.
Então, tive uma epifania. Pensei em verificar o texto de Ajuda para o comando ld:
ld --help
A partir disso, descobri como para executar ld em modo descritivo (imagine que):
ld -lzlib --verbose
Esta é a saída que eu tenho:
==================================================
attempt to open /usr/x86_64-linux-gnu/lib64/libzlib.so failed
attempt to open /usr/x86_64-linux-gnu/lib64/libzlib.a failed
attempt to open /usr/local/lib64/libzlib.so failed
attempt to open /usr/local/lib64/libzlib.a failed
attempt to open /lib64/libzlib.so failed
attempt to open /lib64/libzlib.a failed
attempt to open /usr/lib64/libzlib.so failed
attempt to open /usr/lib64/libzlib.a failed
attempt to open /usr/x86_64-linux-gnu/lib/libzlib.so failed
attempt to open /usr/x86_64-linux-gnu/lib/libzlib.a failed
attempt to open /usr/local/lib/libzlib.so failed
attempt to open /usr/local/lib/libzlib.a failed
attempt to open /lib/libzlib.so failed
attempt to open /lib/libzlib.a failed
attempt to open /usr/lib/libzlib.so failed
attempt to open /usr/lib/libzlib.a failed
/usr/bin/ld.bfd.real: cannot find -lzlib
Ding, ding, ding...
Então, para finalmente corrigi-lo para que eu pudesse compilar o MySQL com a minha própria versão do ZLIB (em vez da versão empacotada):
sudo ln -s /usr/lib/libz.so.1.2.8 /usr/lib/libzlib.so
Voilà!
Durante a compilação com g++
via make
Defina LIBRARY_PATH
Se não for apropriado alterar o Makefile com a opção -L
. Eu tinha colocado a minha biblioteca extra em /opt/lib
Então eu fiz:
$ export LIBRARY_PATH=/opt/lib/
E depois correu make
para compilação e ligação bem sucedidas.
Para executar o programa com uma biblioteca partilhada defina:
$ export LD_LIBRARY_PATH=/opt/lib/
Antes de executar o programa.
Não parece haver nenhuma resposta que resolva o problema muito comum de não instalar a biblioteca necessária em primeiro lugar.
Nas plataformas Debianish, se libfoo
estiver em falta, você pode instalá-lo frequentemente com algo como
apt-get install libfoo-dev
A versão -dev
do pacote é necessária para o trabalho de desenvolvimento, mesmo trabalho de desenvolvimento trivial, como compilar o código fonte para ligar à biblioteca.
O nome do pacote irá, por vezes, necessitar de decorações? foo-dev
sem o prefixo lib
? etc), ou você pode simplesmente usar a pesquisa de pacotes da sua distribuição para descobrir com precisão quais pacotes fornecem um arquivo em particular.
(Se houver mais de um, você precisará descobrir quais são as suas diferenças. Escolher o mais fresco ou o mais popular é um atalho comum, mas não um procedimento aceitável para qualquer trabalho de desenvolvimento sério.)
Para outras arquitecturas (nomeadamente RPM), aplicam-se procedimentos semelhantes, embora o os detalhes serão diferentes.
Tempo De Compilação
Quando o G++ Diz cannot find -l<nameOfTheLibrary>
, significa que o G++ procurou o ficheiro lib{nameOfTheLibrary}.so
, mas não o conseguiu encontrar na localização de pesquisa da Biblioteca partilhada, que por omissão aponta para /usr/lib
e /usr/local/lib
e para outro lugar, talvez.
Para resolver este problema, deverá indicar o ficheiro da Biblioteca (lib{nameOfTheLibrary}.so
) nesses locais de pesquisa ou usar a opção -L
comando. -L{path}
diz ao G++ (Na verdade ld
) para encontrar ficheiros de biblioteca no path {path}
, para além do valor por omissão caminho.
Exemplo: assumindo que tem uma biblioteca em /home/taylor/libswift.so
, e quer ligar a sua aplicação a esta biblioteca. Neste caso, deve fornecer ao G++
as seguintes opções:
g++ main.cpp -o main -L/home/taylor -lswift
Nota 1:
-l
a opção obtém o nome da biblioteca semlib
e {[15] } no seu princípio e fim.Nota 2 : em alguns casos, o nome do ficheiro da Biblioteca é seguido da sua versão, por exemplo
libswift.so.1.2
. Nestes casos, G++ também não é possível encontrar o ficheiro da biblioteca. Uma solução simples para corrigir isso é criar um link simbólico paralibswift.so.1.2
chamadolibswift.so
.
Tempo de execução
Quando você liga a sua aplicação a uma biblioteca partilhada, é necessário que a biblioteca fique disponível sempre que você executar a aplicação. No runtime, o seu aplicativo (na verdade Linker dinâmico) procura por suas bibliotecas em LD_LIBRARY_PATH
. É uma variável de ambiente que armazena uma lista de caminhos.
Exemplo: no caso do nosso libswift.so
exemplo, dinâmica o linker não consegue encontrar libswift.so
em LD_LIBRARY_PATH
(o que aponta para os locais de pesquisa predefinidos). Para corrigir o problema você deve adicionar essa variável com o caminho libswift.so
está dentro.
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/taylor
Quando compilar o seu programa, deverá indicar a localização da biblioteca; em g++, use a opção-L:
g++ myprogram.cc -o myprogram -lmylib -L/path/foo/bar
Este erro também pode ser causado se a ligação simbólica for para uma biblioteca dinâmica, por isso, mas por razões legadas {[[0]} aparece entre as bandeiras do link. Se sim, tente removê-lo.
lxxx
:
/usr/bin/ld: cannot find -lc
/usr/bin/ld: cannot find -lltdl
/usr/bin/ld: cannot find -lXtst
lc
meios libc.so
, lltdl
meios libltdl.so
, lXtst
significa libXts.so
lib
+ lib-name
+ .so
Assim que soubermos o nome, podemos usar locate
para encontrar o caminho deste ficheiro lxxx.so
.
$ locate libiconv.so
/home/user/anaconda3/lib/libiconv.so # <-- right here
/home/user/anaconda3/lib/libiconv.so.2
/home/user/anaconda3/lib/libiconv.so.2.5.1
/home/user/anaconda3/lib/preloadable_libiconv.so
/home/user/anaconda3/pkgs/libiconv-1.14-0/lib/libiconv.so
/home/user/anaconda3/pkgs/libiconv-1.14-0/lib/libiconv.so.2
/home/user/anaconda3/pkgs/libiconv-1.14-0/lib/libiconv.so.2.5.1
/home/user/anaconda3/pkgs/libiconv-1.14-0/lib/preloadable_libiconv.so
Se não o encontrar, Tem de o instalar por yum
(Eu uso CentOS). Normalmente você tem este arquivo, mas ele não link para o lugar certo.
Liga-o ao sítio certo., normalmente é
/lib64
ou /usr/lib64
$ sudo ln -s /home/user/anaconda3/lib/libiconv.so /usr/lib64/
Ref: https://i-pogo.blogspot.jp/2010/01/usrbinld-cannot-find-lxxx.html
Verifique a localização da sua biblioteca, por exemplo lxxx.so:
locate lxxx.so
Se não estiver na pasta /usr/lib
, escreva isto:
sudo cp yourpath/lxxx.so /usr/lib
Feito.
A biblioteca para a qual eu estava a tentar ligar revelou ter um nome não-padrão (ou seja, não estava prefixado com 'lib'), por isso recomendaram a utilização de um comando como este para compilar isto -
gcc test.c -Iinclude lib/cspice.a -lm
Além das respostas já dadas, também pode ser o caso de o ficheiro *.so existir, mas não ser devidamente nomeado. Ou pode ser o caso que o ficheiro *.so existe, mas pertence a outro utilizador / root.
Questão 1: nome impróprio
Se estiver a ligar o ficheiro como -l<nameOfLibrary>
então o nome do arquivo da biblioteca deve ser do formulário lib<nameOfLibrary>
Se você só tem Arquivo <nameOfLibrary>.so
, renomeie-o!
Questão 2: proprietário errado
Para verificar que este não é o problema - do
ls -l /path/to/.so/file
Se o ficheiro pertence ao root ou a outro utilizador, tem de o fazer
sudo chown yourUserName:yourUserName /path/to/.so/file
O meu problema era que eu renomeei o directório-mãe do programa que estava a executar ({[[[0]} de MVAPICH), e de alguma forma estragou o binário. Mesmo pré-indexando LD_ LIBRARY_PATH não foi suficiente e eu tive que re-compilá-lo para o caminho correto.