it-swarm.it

usr/bin/ld: impossibile trovare -l <nameOfTheLibrary>

Sto cercando di compilare il mio programma e restituisce questo errore:

usr/bin/ld: cannot find -l<nameOfTheLibrary>

nel mio makefile uso il comando g++ e il link alla mia libreria che è un link simbolico alla mia libreria situata su un'altra directory.

C'è un'opzione da aggiungere per farlo funzionare per favore?

327
ZoOo

Se il nome della tua libreria è say libxyz.so e si trova sul percorso, dì:

/home/user/myDir

quindi per collegarlo al tuo programma:

g++ -L/home/user/myDir -lxyz myprog.cpp -o myprog
148
Saurabh Bhola

Per capire cosa sta cercando il linker, eseguilo in modalità dettagliata. 

Ad esempio, ho riscontrato questo problema durante il tentativo di compilare MySQL con il supporto ZLIB. Stavo ricevendo un errore come questo durante la compilazione:

/usr/bin/ld: cannot find -lzlib

Ho fatto un po 'di googl'ing e ho continuato a imbattersi in diversi problemi dello stesso tipo in cui la gente avrebbe detto per assicurarsi che il file .so esistesse realmente e se non lo fosse, quindi creare un link simbolico al file versionato, per esempio, zlib. so.1.2.8. Ma quando ho controllato, esistono zlib.so DID. Quindi, ho pensato, sicuramente questo non potrebbe essere il problema. 

Mi sono imbattuto in un altro post sugli Internets che suggeriva di eseguire make con LD_DEBUG = all:

LD_DEBUG=all make

Sebbene abbia ottenuto un output TON di debug, non è stato di grande aiuto. Ha aggiunto più confusione di ogni altra cosa. Quindi, stavo per arrendermi.

Poi, ho avuto un'illuminazione. Ho pensato di controllare effettivamente il testo di aiuto per il comando ld:

ld --help

Da ciò ho capito come eseguire ld in modalità dettagliata (immaginatelo):

ld -lzlib --verbose

Questo è l'output che ho ottenuto:

==================================================
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 ...

Quindi, per risolverlo definitivamente in modo da poter compilare MySQL con la mia versione di ZLIB (piuttosto che la versione in bundle):

Sudo ln -s /usr/lib/libz.so.1.2.8 /usr/lib/libzlib.so

Ecco!

363
dcarrith

Durante la compilazione con g++ via make definire LIBRARY_PATH se potrebbe non essere appropriato cambiare il Makefile con -Loption. Ho messo la mia libreria extra in /opt/lib così ho fatto: 

$ export LIBRARY_PATH=/opt/lib/

e poi ha eseguito make per compilare e collegare correttamente.

Per eseguire il programma con una libreria condivisa definire:

$ export LD_LIBRARY_PATH=/opt/lib/

prima di eseguire il programma.

28

Non sembra esserci alcuna risposta che affronta il problema principiante molto comune di non riuscire a installare la libreria richiesta in primo luogo.

Su piattaforme Debianish, se manca libfoo, puoi installarlo frequentemente con qualcosa di simile

apt-get install libfoo-dev

La versione -dev del pacchetto è necessaria per il lavoro di sviluppo, anche per lavori di sviluppo banali come la compilazione di codice sorgente per il collegamento alla libreria.

A volte il nome del pacchetto richiede alcune decorazioni (libfoo0-dev? foo-dev senza il prefisso lib? Ecc.), Oppure puoi semplicemente usare il tuo package search della distro per scoprire con precisione quali pacchetti forniscono un particolare file.

(Se ce n'è più di uno, dovrai scoprire quali sono le loro differenze. Scegliere il più bello o il più popolare è una scorciatoia comune, ma non una procedura accettabile per qualsiasi serio lavoro di sviluppo.)

Per altre architetture (in particolare RPM) si applicano procedure simili, anche se i dettagli saranno diversi.

25
tripleee

Compilare il tempo

Quando G ++ dice cannot find -l<nameOfTheLibrary>, significa che G ++ ha cercato il file lib{nameOfTheLibrary}.so, ma non è riuscito a trovarlo nel percorso di ricerca della libreria condivisa, che per default punta a /usr/lib e /usr/local/lib e da qualche altra parte forse.

Per risolvere questo problema, è necessario fornire il file della libreria (lib{nameOfTheLibrary}.so) in quei percorsi di ricerca o utilizzare l'opzione di comando -L. -L{path} indica al G ++ (in realtà ld) di trovare i file della libreria nel percorso {path} oltre ai percorsi predefiniti.

Esempio: Supponendo che tu abbia una libreria su /home/taylor/libswift.so, e vuoi collegare la tua app a questa libreria. In questo caso devi fornire G++con le seguenti opzioni:

g++ main.cpp -o main -L/home/taylor -lswift
  • Nota 1 : -l opzione ottiene il nome della libreria senzalib e .so all'inizio e alla fine.

  • Nota 2 : In alcuni casi, il nome del file della libreria è seguito dalla sua versione, ad esempio libswift.so.1.2. In questi casi, G ++ non riesce a trovare il file della libreria. Un semplice rimedio per risolvere questo problema è la creazione di un collegamento simbolico a libswift.so.1.2 chiamato libswift.so.


Runtime

Quando colleghi la tua app a una libreria condivisa, è necessario che la libreria rimanga disponibile ogni volta che esegui l'app. In runtime la tua app (in pratica linker dinamico) cerca le sue librerie in LD_LIBRARY_PATH. È una variabile di ambiente che memorizza un elenco di percorsi.

Esempio: Nel nostro esempio libswift.so, il linker dinamico non riesce a trovare libswift.so in LD_LIBRARY_PATH (che punta ai percorsi di ricerca predefiniti). Per risolvere il problema devi aggiungere la variabile con il percorso libswift.so.

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/taylor
23
Hi I'm Frogatto

Innanzitutto, è necessario conoscere la regola di denominazione di lxxx:

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

lc significa libc.so, lltdl significa libltdl.so, lXtst significa libXts.so.

Quindi, lib + lib-name + .so


Una volta che conosciamo il nome, possiamo usare locate per trovare il percorso di questo file 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 non riesci a trovarlo, devi installarlo con yum (utilizzo CentOS). Di solito hai questo file, ma non si collega al posto giusto.


Collegalo al posto giusto, solitamente /lib64 o /usr/lib64

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

Fatto!

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

5
Belter

Quando compili il tuo programma devi fornire il percorso alla biblioteca; in g ++ usa l'opzione -L:

g++ myprogram.cc -o myprogram -lmylib -L/path/foo/bar
4
koan

Controlla la posizione della tua libreria, ad esempio lxxx.so: 

locate lxxx.so

Se non è nella cartella /usr/lib, digita questo:

Sudo cp yourpath/lxxx.so /usr/lib

Fatto.

2
hua

Questo errore può anche essere generato se il collegamento simbolico è in una libreria dinamica, .so, ma per motivi legacy -static viene visualizzato tra i flag di collegamento. Se è così, prova a rimuoverlo.

2
Vzbux

Oltre alle risposte già fornite, potrebbe anche accadere che il file * .so esista ma non sia nominato correttamente. O potrebbe essere il caso che il file * .so esista ma sia di proprietà di un altro utente/root.

Numero 1: Nome improprio 

Se si collega il file come -l<nameOfLibrary>, Il nome del file della libreria DEVE essere di tipo lib<nameOfLibrary> Se si ha solo il file <nameOfLibrary>.so, rinominarlo!

Numero 2: Proprietario errato

Per verificare che questo non sia il problema, fallo

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

Se il file è di proprietà di root o di un altro utente, è necessario farlo

Sudo chown yourUserName:yourUserName /path/to/.so/file
1
user13107

La libreria che stavo cercando di collegare si è rivelata avere un nome non standard (non era prefisso con 'lib'), quindi hanno raccomandato di usare un comando come questo per compilarlo - 

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

1
Brian Burns

Il mio problema è stato che ho rinominato la directory principale del programma che stavo correndo (mpicc di MVAPICH), e in qualche modo ha rovinato il binario. Anche l'esecuzione anticipata di LD_LIBRARY_PATH non è stata sufficiente e ho dovuto ricompilarlo nel percorso corretto.

0
Alberto Chiusole