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


444

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 che si trova su un'altra directory.

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


1
Hai bisogno di maggiori informazioni. Quale comando hai emesso per compilare il tuo programma? Puoi usare make -n your-target per fare solo stampare i comandi che normalmente invocherebbe
djf

Pubblica il makefile o il comando che esegui.
Ortwin Angermeier,

il mio comando è questo: g ++ - <opzioni> objetc1.o objetc2.o objetc3.o objetc4.o -L <pathOfTheLibrary> -l <nameOfTheLibrary> -lpthread -o myexe
ZoOo

4
La libreria con cui vuoi collegarti è costruita con la stessa architettura (es. 32/64 bit)? La libreria che desideri collegare a una libreria personalizzata? Il nome della libreria è importante, poiché deve iniziare con lib <name> quando si usa l' -lopzione (es. Libpthread.so con cui ci si sta già collegando).
Ortwin Angermeier,

1
Il problema era sul mio link simbolico nella libreria che non era buono! Grazie per l'aiuto !
ZoOo,

Risposte:


196

Se il nome della tua libreria è dire libxyz.soe si trova sul percorso, dire:

/home/user/myDir

quindi per collegarlo al tuo programma:

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

11
la mia libreria non è dinamica (.so) ma statica (.a). Il problema deriva da quello?
ZoOo,

3
@ZoOo che normalmente non dovrebbe importare, il linker può funzionare con uno dei due
djf

7
un altro modo per collegare la tua libreria è che puoi specificare direttamente il nome della libreria con il percorso completo, come g ++ .. /path/mylib.a
Saurabh Bhola,

2
Sì, ma non funziona ancora. La mia libreria è un collegamento simbolico, penso che il problema derivi da quello perché quando uso la libreria nell'altra directory funziona!
ZoOo,

2
Il tuo link simbolico punta correttamente alla libreria nella posizione effettiva ??. puoi pubblicare l'output di "ll" sul link simbolico.
Saurabh Bhola,

452

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 del genere durante la compilazione:

/usr/bin/ld: cannot find -lzlib

Ho fatto un po 'di googl'ing e ho continuato a imbattermi in diversi problemi dello stesso tipo in cui le persone direbbero per assicurarsi che il file .so esista effettivamente e, in caso contrario, quindi creare un link simbolico al file con versione, ad esempio zlib. so.1.2.8. Ma, quando ho controllato, zlib.so DID esiste. Quindi, ho pensato, sicuramente non poteva essere questo il problema.

Mi sono imbattuto in un altro post su Internet che ha suggerito di eseguire make con LD_DEBUG = all:

LD_DEBUG=all make

Anche se ho avuto un sacco di output di debug, in realtà non è stato utile. Ha aggiunto più confusione di ogni altra cosa. Quindi stavo per arrendermi.

Poi, ho avuto un'epifania. 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 (immagina):

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 finalmente 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!


60
Grazie, questo è stato utile. Per altri che usano gcc per compilare e collegare il loro programma (piuttosto che usare direttamente ld), è possibile aggiungere -Xlinker --verboseagli argomenti della riga di comando di gcc per far passare questa opzione a ld.

5
Questo mi ha anche aiutato. Il Makefile che avevo aspettava solo librerie statiche, quindi è stato usato -Wl,-Bstatic. Ciò limita la ricerca solo ai file .a. L'opzione dettagliata lo ha mostrato chiaramente. Una volta rimossi -Wl,-Bstaticsono state anche cercate le librerie condivise.
micah94,

2
Sono su FreeBSD 10. Il nuovo LLVM Clang cc accetta un argomento del modulo -Wl,--verbosee passa --verboseal linker.
Christian Campbell,

7
Questo è quello che chiamo una risposta perfetta! Molte grazie. Ha risparmiato un sacco di tempo. Solo per aggiungere per aiutare qualcuno come me. Può essere utilizzato anche per eseguire il debug di problemi relativi al percorso. Assicurati di controllare il percorso con -L <percorso della directory> con comando, ld -L <percorso> -l <nome libreria> --verbose
sbhatt

2
@EdwardBlack Vedi questa risposta . In sostanza, per gcc, basta aggiungere -Wl,--verboseper passare verbose al linker.
Chembrad

46

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

Su piattaforme Debianish, se libfoomanca, puoi installarlo frequentemente con qualcosa del genere

apt-get install libfoo-dev

La -devversione del pacchetto è necessaria per il lavoro di sviluppo, anche per un banale lavoro di sviluppo come la compilazione di codice sorgente da collegare alla libreria.

Il nome del pacchetto a volte richiederà alcune decorazioni ( libfoo0-dev? foo-devSenza il libprefisso? Ecc.), Oppure puoi semplicemente usare la ricerca dei pacchetti della tua distribuzione per scoprire con precisione quali pacchetti forniscono un determinato 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.


3
Questo mi ha solo aiutato con un problema che stavo riscontrando con un nuovo server e Perl. apt-get install libperl-devrisolto per me. Grazie :)
Andrew Newby,

1
Questo! Non c'è bisogno di scherzare con il Makefile
Byron Whitlock,

Questa è probabilmente la soluzione più comune e mi ha aiutato a compilare cactus-colonna vertebrale su CentOS 7. Un semplice yum install openssl-develrisolto.
djluko,

1
Questa è la soluzione migliore se trovi che il link simbolico che termina in .so è mancante, ma hai un link simbolico come libfoo.so.6 -> libfoo.so.6.0.2 (per esempio), invece di creare il link simbolico con mano. (significa che hai installato il pacchetto libfoo, ma non libfoo-dev)
dmaestro12

39

Tempo di compilazione

Quando g ++ dice cannot find -l<nameOfTheLibrary>, vuol dire che g ++ cercato il file lib{nameOfTheLibrary}.so, ma non riusciva a trovare nel percorso di ricerca della libreria condivisa, che per i punti predefiniti /usr/libe /usr/local/libe forse da qualche altra parte.

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

Esempio: supponendo che tu abbia una libreria in /home/taylor/libswift.soe desideri collegare la tua app a questa libreria. In questo caso dovresti fornire a g ++ le seguenti opzioni:

g++ main.cpp -o main -L/home/taylor -lswift
  • Nota 1 : l' -lopzione ottiene il nome della libreria senza lib e .soall'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, anche g ++ non riesce a trovare il file di libreria. Una semplice soluzione per risolvere questo problema è la creazione di un collegamento simbolico a libswift.so.1.2chiamato libswift.so.


Runtime

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

Esempio: nel nostro libswift.soesempio, il linker dinamico non trova libswift.soin LD_LIBRARY_PATH(che punta a percorsi di ricerca predefiniti). Per risolvere il problema dovresti aggiungere quella variabile con il percorso libswift.so.

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/taylor

Grazie per il tuo post! Ho ignorato tutte le risposte fino al momento in cui ho copiato i .sofile /usr/lib, ma è diventato interessante per me se mi exportaiuterà. Nonostante il processo di installazione sia makecontinuato più a lungo, si è verificato un altro errore. Questa volta, il .so.0file non è stato trovato, ma entrambi .soe il .so.0file erano nella directory in cui ho creato il pacchetto dipendente dalla fonte. Potresti aiutarci?
A.Ametov,

33

Durante la compilazione con g++via makedefine LIBRARY_PATHse potrebbe non essere appropriato cambiare il Makefile con l' -Lopzione. Avevo inserito la mia libreria extra /opt/libcosì ho fatto:

$ export LIBRARY_PATH=/opt/lib/

e poi ha funzionato makeper compilazione e collegamento riusciti.

Per eseguire il programma con una libreria condivisa definire:

$ export LD_LIBRARY_PATH=/opt/lib/

prima di eseguire il programma.


14

Innanzitutto, devi 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

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

Quindi è lib+ lib-name+.so


Una volta che conosciamo il nome, possiamo usare locateper trovare il percorso di questo lxxx.sofile.

$ 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 da yum(io uso CentOS). Di solito hai questo file, ma non si collega al posto giusto.


Collegalo nel posto giusto, di solito lo è /lib64o/usr/lib64

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

Fatto!

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


4
locateFunziona solo se è installato e funzionante regolarmente. Una soluzione approssimativa è eseguire findsu tutto il disco, ma ovviamente ci vorrà del tempo. Se ti ritrovi a farlo di frequente, considera l'installazione locatesolo per ridurre il costo (interattivo, umano) di questa operazione.
triplo il

5

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

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

1
In quale proprietà dobbiamo modificare in ccmakemodo che Makefilevenga creato con il flag collegato? Voglio collegare la mia -lARToolkitPlusbandiera a un percorso.
Shashwat,

2

Questo errore può anche essere causato se il collegamento simbolico è a una libreria dinamica, .so, ma per motivi legacy -staticappare tra i flag di collegamento. In tal caso, prova a rimuoverlo.


2

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

locate lxxx.so

Se non si trova nella /usr/libcartella, digitare questo:

sudo cp yourpath/lxxx.so /usr/lib

Fatto.


4
È necessario prestare attenzione nel copiare le librerie nelle directory di sistema.
Paul Floyd,

2

A parte le risposte già fornite, è possibile che il file * .so esista ma non sia stato nominato correttamente. Oppure può esistere il file * .so ma è di proprietà di un altro utente / root.

Problema 1: nome errato

Se stai collegando il file come -l<nameOfLibrary> allora il nome del file della libreria DEVE essere nel formato lib<nameOfLibrary> Se hai solo un <nameOfLibrary>.sofile, rinominalo!

Problema 2: proprietario errato

Per verificare che questo non sia il problema, esegui

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

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

sudo chown yourUserName:yourUserName /path/to/.so/file

1

La libreria a cui stavo cercando di collegare aveva un nome non standard (cioè non era preceduto da "lib"), quindi mi hanno consigliato di usare un comando come questo per compilarlo -

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


Il prefisso solo con "lib" per ottenere un nome standard corretto per me
el_technic0

1

Ecco le informazioni di Ubuntu sul mio laptop.

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

Uso individuare per trovare i file .so per boost_filesystem e boost_system

locate libboost_filesystem
locate libboost_system

Quindi collegare i file .so a / usr / lib e rinominarli in .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

Fatto! Il pacchetto R velocyto.R è stato installato con successo!


1

Ho riscontrato lo stesso messaggio di errore.

Ho creato l' cmockaAS soe ho provato a collegarlo al mio eseguibile. Ma ldsi lamenta sempre di seguito:

/ usr / bin / ld: impossibile trovare -lcmocka

Si scopre che ci sono 3 file generati dopo la cmockacreazione:

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

1 e 2 sono collegamenti di simboli e solo 3 è il file reale.

Ho solo copiato l'1 nella mia cartella della libreria, dove ldnon è stato possibile trovare il 3.

Dopo aver copiato tutti e 3, ldfunziona.


Puoi dirmi per favore quale cartella intendi sotto "la mia cartella della biblioteca"?
A.Ametov,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.