usr / bin / ld: não é possível encontrar -l <nameOfTheLibrary>

443

Estou tentando compilar meu programa e ele retorna 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 localizada em outro diretório.

Existe uma opção para adicionar para que funcione, por favor?

ZoOo
fonte
1
Precisa de mais informações. Qual comando você emitiu para compilar seu programa? Você pode usar make -n seu alvo de ter make apenas imprimir os comandos que normalmente invoke
djf
Poste o makefile ou o comando que você executa.
Ortwin Angermeier
meu comando é este: g ++ - <opções> objetc1.o objetc2.o objetc3.o objetc4.o -L <pathOfTheLibrary> -l <nameOfTheLibrary> -lpthread -o myexe
ZoOo
4
A biblioteca com a qual você deseja vincular foi criada com a mesma arquitetura (por exemplo, 32/64 bits)? A biblioteca que você deseja vincular a uma biblioteca personalizada? O nome da biblioteca é importante, pois ele deve começar com lib <name> ao usar a -lopção (por exemplo, libpthread.so com o qual você já está se vinculando).
Ortwin Angermeier
1
O problema estava no meu link simbólico na biblioteca, o que não era bom! Obrigado pela ajuda !
ZoOo 23/05

Respostas:

196

Se o nome da sua biblioteca for say libxyz.soe estiver localizado no caminho, diga:

/home/user/myDir

depois, vincule-o ao seu programa:

g++ -L/home/user/myDir -lxyz myprog.cpp -o myprog
Saurabh Bhola
fonte
11
minha biblioteca não é dinâmica (.so), mas estática (.a). O problema vem disso?
ZoOo 23/05
3
@ZoOo que não deve normalmente matéria, o ligador pode trabalhar com qualquer um
djf
7
outra maneira de vincular sua biblioteca é que você pode especificar diretamente o nome da biblioteca com o caminho completo, como g ++ .. /path/mylib.a
Saurabh Bhola
2
Sim, mas ainda não funciona. Minha biblioteca é um link simbólico, acho que o problema vem disso, porque quando eu uso a biblioteca no outro diretório, ela funciona!
ZoOo 23/05
2
O seu link simbólico está apontando corretamente para a biblioteca no local real ??. você pode postar a saída de "ll" no link simbólico.
Saurabh Bhola
450

Para descobrir o que o vinculador está procurando, execute-o no modo detalhado.

Por exemplo, eu encontrei esse problema ao tentar compilar o MySQL com suporte ao ZLIB. Eu estava recebendo um erro como este durante a compilação:

/usr/bin/ld: cannot find -lzlib

Eu fiz algumas pesquisas e continuei encontrando diferentes problemas do mesmo tipo, onde as pessoas diriam para garantir que o arquivo .so realmente exista e, se não existir, crie um link simbólico para o arquivo com versão, por exemplo, zlib. so.1.2.8. Mas, quando eu verifiquei, o zlib.so existia. Então, pensei, certamente esse não poderia ser o problema.

Me deparei com outro post no Internets que sugeria executar make com LD_DEBUG = all:

LD_DEBUG=all make

Embora eu tenha uma tonelada de resultados de depuração, não foi realmente útil. Acrescentou mais confusão do que qualquer outra coisa. Então, eu estava prestes a desistir.

Então, eu tive uma epifania. Eu pensei em realmente verificar o texto de ajuda para o comando ld:

ld --help

A partir disso, eu descobri como executar ld no modo detalhado (imagine isso):

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 consertá-lo para que eu pudesse compilar o MySQL com 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

Voila!

dcarrith
fonte
60
Obrigado, isso foi útil. Para outras pessoas que usam o gcc para compilar e vincular seu programa (em vez de usar o ld diretamente), você pode adicionar -Xlinker --verboseaos argumentos da linha de comando do gcc para que ele passe essa opção para o ld.
5
Isso também me ajudou. O Makefile que eu tinha estava esperando apenas bibliotecas estáticas, então foi usado -Wl,-Bstatic. Isso limita a pesquisa apenas aos arquivos .a. A opção detalhada mostrou isso claramente. Depois que eu removi -Wl,-Bstaticas bibliotecas compartilhadas, também foram pesquisadas.
Micah94 23/02
2
Estou no FreeBSD 10. O novo LLVM Clang cc pega um argumento do formulário -Wl,--verbosee passa --verbosepara o vinculador.
Christian Campbell
7
Agora é isso que chamo de resposta perfeita! Muito obrigado. Economizou muito tempo. Apenas para adicionar para ajudar alguém como eu. Também pode ser usado para depurar problemas relacionados ao caminho. Certifique-se de verificar o caminho com -L <caminho para o diretório> com o comando, ld -L <caminho> -l <nome da biblioteca> --verbose
sbhatt
2
@EdwardBlack Veja esta resposta . Essencialmente, para o gcc, basta adicionar -Wl,--verbosepara passar detalhes ao vinculador.
chembrad
46

Parece não haver nenhuma resposta que resolva o problema iniciante muito comum de não instalar a biblioteca necessária em primeiro lugar.

Nas plataformas Debianish, se libfooestiver faltando, você pode instalá-lo frequentemente com algo como

apt-get install libfoo-dev

A -devversão do pacote é necessária para o trabalho de desenvolvimento, mesmo o trabalho trivial de desenvolvimento, como compilar o código-fonte para vincular à biblioteca.

Às vezes, o nome do pacote requer algumas decorações ( libfoo0-dev? foo-devSem o libprefixo? Etc), ou você pode simplesmente usar a pesquisa de pacotes da sua distribuição para descobrir com precisão quais pacotes fornecem um arquivo específico.

(Se houver mais de um, você precisará descobrir quais são suas diferenças. Escolher o mais legal ou o mais popular é um atalho comum, mas não um procedimento aceitável para qualquer trabalho sério de desenvolvimento.)

Para outras arquiteturas (principalmente RPM), procedimentos semelhantes se aplicam, embora os detalhes sejam diferentes.

triplo
fonte
3
Isso só me ajudou com um problema que eu estava tendo com um servidor novo e o Perl. apt-get install libperl-devresolvi para mim. Obrigado :)
Andrew Newby
1
Este! Não há necessidade de mexer com o Makefile
Byron Whitlock
Esta é provavelmente a solução mais comum e me ajudou a compilar cactos-espinha no CentOS 7. Uma yum install openssl-develsolução simples .
djluko
1
Essa é a melhor correção se você encontrar o link simbólico terminado em .so, mas tiver um link simbólico como libfoo.so.6 -> libfoo.so.6.0.2 (por exemplo), em vez de criar o link simbólico por mão. (o que significa que você tem o pacote libfoo instalado, mas não o libfoo-dev)
dmaestro12,
39

Tempo de compilação

Quando o g ++ diz cannot find -l<nameOfTheLibrary>, significa que o g ++ procurou o arquivo lib{nameOfTheLibrary}.so, mas não conseguiu encontrá-lo no caminho de pesquisa da biblioteca compartilhada, que por padrão aponta para /usr/libe/usr/local/lib e outro lugar talvez.

Para resolver esse problema, você deve fornecer o arquivo de biblioteca ( lib{nameOfTheLibrary}.so) nesses caminhos de pesquisa ou usar a -Lopção de comando -L{path}diz ao g ++ (na verdade ld) para encontrar os arquivos da biblioteca no caminho {path}, além dos caminhos padrão.

Exemplo: Supondo que você tenha uma biblioteca /home/taylor/libswift.soe que deseja vincular seu aplicativo a essa biblioteca. Nesse caso, você deve fornecer ao g ++ as seguintes opções:

g++ main.cpp -o main -L/home/taylor -lswift
  • Nota 1 : a -lopção obtém o nome da biblioteca sem lib e .sono início e no final.

  • Nota 2 : Em alguns casos, o nome do arquivo da biblioteca é seguido por sua versão, por exemplo libswift.so.1.2. Nesses casos, o g ++ também não pode encontrar o arquivo da biblioteca. Uma solução simples para corrigir isso é criar um link simbólico para libswift.so.1.2chamado libswift.so.


Tempo de execução

Quando você vincula seu aplicativo a uma biblioteca compartilhada, é necessário que a biblioteca permaneça disponível sempre que você o executar. Em tempo de execução, seu aplicativo (na verdade, vinculador dinâmico) procura suas bibliotecas no LD_LIBRARY_PATH. É uma variável de ambiente que armazena uma lista de caminhos.

Exemplo: no caso do nosso libswift.soexemplo, o vinculador dinâmico não pode ser encontrado libswift.soem LD_LIBRARY_PATH(que aponta para os caminhos de pesquisa padrão). Para corrigir o problema, você deve anexar essa variável ao caminho libswift.so.

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/taylor
frogatto
fonte
Obrigado pelo seu post! Eu tenho ignorado todas as respostas até o momento em que copiei os .soarquivos /usr/lib, mas ficou interessante para mim se exportisso ajudaria. Apesar do processo de instalação após makecontinuar por mais tempo, ocorreu outro erro. Desta vez, o .so.0arquivo não foi encontrado, mas ambos .soe .so.0file estavam no diretório em que eu construí o pacote dependente da origem. Você poderia ajudar com isso?
A.Ametov 24/01
33

Durante a compilação com g++via makedefine LIBRARY_PATHse pode não ser apropriado alterar o Makefile com a -Lopção Eu tinha colocado minha biblioteca extra, /opt/libentão fiz:

$ export LIBRARY_PATH=/opt/lib/

e depois correu makepara compilação e vinculação bem-sucedidas.

Para executar o programa com uma biblioteca compartilhada, defina:

$ export LD_LIBRARY_PATH=/opt/lib/

antes de executar o programa.

Finn Årup Nielsen
fonte
14

Primeiro, você precisa conhecer a regra de nomeação de lxxx:

/usr/bin/ld: cannot find -lc
/usr/bin/ld: cannot find -lltdl
/usr/bin/ld: cannot find -lXtst

lcsignifica libc.so, lltdlsignifica libltdl.so, lXtstsignifica libXts.so.

Então é lib+ lib-name+.so


Depois que soubermos o nome, podemos usar locatepara encontrar o caminho desse lxxx.soarquivo.

$ 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 você não conseguir encontrá-lo, precisará instalá-lo yum(eu uso o CentOS). Normalmente você tem esse arquivo, mas ele não está vinculado ao lugar certo.


Ligue-o ao local certo, geralmente é /lib64ou/usr/lib64

$ sudo ln -s /home/user/anaconda3/lib/libiconv.so /usr/lib64/

Feito!

ref: https://i-pogo.blogspot.jp/2010/01/usrbinld-cannot-find-lxxx.html

Belter
fonte
4
locatesó funciona se estiver instalado e funcionando regularmente. Uma solução alternativa é executar findem todo o disco, mas é claro que isso levará tempo. Se você fizer isso com frequência, considere instalar locateapenas para reduzir o custo (interativo, humano) dessa operação.
tripleee
5

Ao compilar seu programa, você deve fornecer o caminho para a biblioteca; no g ++, use a opção -L:

g++ myprogram.cc -o myprogram -lmylib -L/path/foo/bar
koan
fonte
1
Em qual propriedade precisamos alterar ccmakepara que Makefileseja criada com o sinalizador vinculado? Quero vincular minha -lARToolkitPlusbandeira a um caminho.
Shashwat
2

Esse erro também pode ser causado se o link simbólico for para uma biblioteca dinâmica, .so, mas por motivos herdados -staticaparecer entre os sinalizadores de link. Nesse caso, tente removê-lo.

Vzbux
fonte
2

Verifique a localização da sua biblioteca, por exemplo lxxx.so:

locate lxxx.so

Se não estiver na /usr/libpasta, digite o seguinte:

sudo cp yourpath/lxxx.so /usr/lib

Feito.

hua
fonte
4
Você precisa ter cuidado ao copiar bibliotecas para diretórios do sistema.
Paul Floyd
2

Além das respostas já fornecidas, também pode ser que o arquivo * .so exista, mas não seja nomeado corretamente. Ou pode ser que o arquivo * .so exista, mas seja de propriedade de outro usuário / raiz.

Problema 1: nome impróprio

Se você estiver vinculando o arquivo -l<nameOfLibrary> , o nome do arquivo da biblioteca DEVE estar no formato lib<nameOfLibrary> Se você tiver apenas um <nameOfLibrary>.soarquivo, renomeie-o!

Edição 2: proprietário errado

Para verificar se esse não é o problema - faça

ls -l /path/to/.so/file

Se o arquivo pertencer à raiz ou a outro usuário, você precisará fazer

sudo chown yourUserName:yourUserName /path/to/.so/file
user13107
fonte
1

A biblioteca que eu estava tentando vincular tinha um nome não padrão (ou seja, não era prefixado com 'lib'), então eles recomendaram o uso de um comando como este para compilá-lo -

gcc test.c -Iinclude lib/cspice.a -lm

Brian Burns
fonte
Apenas prefixando com "lib" para obter um nome de padrão fixo para mim
el_technic0
1

Aqui estão as informações do Ubuntu do meu laptop.

lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 18.04.2 LTS
Release:    18.04
Codename:   bionic

Eu uso o find para encontrar os arquivos .so para boost_filesystem e boost_system

locate libboost_filesystem
locate libboost_system

Em seguida, vincule os arquivos .so a / usr / lib e renomeie para .so

sudo ln -s /usr/lib/x86_64-linux-gnu/libboost_filesystem.so.1.65.1 /usr/lib/libboost_filesystem.so
sudo ln -s /usr/lib/x86_64-linux-gnu/libboost_system.so.1.65.1 /usr/lib/libboost_system.so

Feito! O pacote R velocyto.R foi instalado com sucesso!

Shicheng Guo
fonte
1

Eu encontrei a mesma mensagem de erro.

Eu construí o cmockaas soe tentei vinculá-lo ao meu executável. Mas ldsempre reclama abaixo:

/ usr / bin / ld: não é possível encontrar -lcmocka

Acontece que existem três arquivos gerados após a cmockacompilação:

  1. libcmocka.so
  2. libcmocka.so.0
  3. libcmocka.so.0.7.0

1 e 2 são links de símbolos e apenas 3 é o arquivo real.

Eu apenas copiei o 1 na pasta da minha biblioteca, onde ldnão encontrei o 3.

Depois de copiar todos os 3, ldfunciona.

smwikipedia
fonte
Você pode dizer, por favor, qual pasta você quer dizer em "minha pasta da biblioteca"?
A.Ametov 24/01