usr / bin / ld: -l <nameOfTheLibrary> kann nicht gefunden werden

443

Ich versuche mein Programm zu kompilieren und es gibt diesen Fehler zurück:

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

In meinem Makefile verwende ich den Befehl g++und den Link zu meiner Bibliothek. Dies ist ein symbolischer Link zu meiner Bibliothek in einem anderen Verzeichnis.

Gibt es eine Option zum Hinzufügen, damit es funktioniert?

ZoOo
quelle
1
Benötigen Sie weitere Informationen. Welchen Befehl haben Sie ausgegeben, um Ihr Programm zu kompilieren? Sie können make -n your-target verwenden , damit make nur die Befehle druckt, die normalerweise
aufgerufen werden
Veröffentlichen Sie das Makefile oder den Befehl, den Sie ausführen.
Ortwin Angermeier
Mein Befehl lautet wie folgt: g ++ - <Optionen> objetc1.o objetc2.o objetc3.o objetc4.o -L <PfadOfTheLibrary> -l <NameOfTheLibrary> -lpthread -o myexe
ZoOo
4
Ist die Bibliothek, mit der Sie verknüpfen möchten, mit derselben Architektur erstellt (z. B. 32/64 Bit)? Ist die Bibliothek, die Sie mit einer benutzerdefinierten Bibliothek verknüpfen möchten? Der Bibliotheksname ist wichtig, da er bei Verwendung des -lSchalters mit lib <Name> beginnen muss (z. B. libpthread.so, mit dem Sie bereits verknüpfen).
Ortwin Angermeier
1
Das Problem war auf meinem symbolischen Link in der Bibliothek, der nicht gut war! Danke für Ihre Hilfe !
ZoOo

Antworten:

196

Wenn Ihr Bibliotheksname say lautet libxyz.sound er sich auf dem Pfad befindet, sagen Sie:

/home/user/myDir

dann, um es mit Ihrem Programm zu verknüpfen:

g++ -L/home/user/myDir -lxyz myprog.cpp -o myprog
Saurabh Bhola
quelle
11
Meine Bibliothek ist keine dynamische (.so), sondern eine statische (.a). Kommt das Problem daraus?
ZoOo
3
@ ZoOo das sollte normalerweise keine Rolle spielen, der Linker kann mit beiden arbeiten
DJF
7
Eine andere Möglichkeit, Ihre Bibliothek zu verknüpfen, besteht darin, dass Sie den Namen der Bibliothek direkt mit dem vollständigen Pfad angeben können, z. B. g ++ .. /path/mylib.a
Saurabh Bhola
2
Ja, aber es funktioniert immer noch nicht. Meine Bibliothek ist ein symbolischer Link, ich denke, das Problem liegt darin, dass es funktioniert, wenn ich die Bibliothek im anderen Verzeichnis verwende!
ZoOo
2
Zeigt Ihr symbolischer Link korrekt auf die Bibliothek am tatsächlichen Standort? Kannst du die Ausgabe von "ll" auf dem symbolischen Link posten?
Saurabh Bhola
450

Um herauszufinden, wonach der Linker sucht, führen Sie ihn im ausführlichen Modus aus.

Dieses Problem ist beispielsweise beim Kompilieren von MySQL mit ZLIB-Unterstützung aufgetreten. Beim Kompilieren wurde folgende Fehlermeldung angezeigt:

/usr/bin/ld: cannot find -lzlib

Ich habe ein bisschen Googl'ing gemacht und bin immer wieder auf verschiedene Probleme der gleichen Art gestoßen, bei denen die Leute sagten, sie würden sicherstellen, dass die .so-Datei tatsächlich existiert. Wenn dies nicht der Fall ist, erstellen Sie einen Symlink zu der versionierten Datei, z. B. zlib. so.1.2.8. Aber als ich nachgesehen habe, war zlib.so DID vorhanden. Also, dachte ich, das könnte doch nicht das Problem sein.

Ich bin auf einen anderen Beitrag im Internet gestoßen, der vorschlug, make mit LD_DEBUG = all auszuführen:

LD_DEBUG=all make

Obwohl ich eine TONNE Debugging-Ausgabe habe, war es nicht wirklich hilfreich. Es fügte mehr Verwirrung als alles andere hinzu. Also wollte ich aufgeben.

Dann hatte ich eine Offenbarung. Ich dachte, ich sollte den Hilfetext für den Befehl ld überprüfen:

ld --help

Daraus habe ich herausgefunden, wie man ld im ausführlichen Modus ausführt (stellen Sie sich das vor):

ld -lzlib --verbose

Dies ist die Ausgabe, die ich erhalten habe:

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

Um es endlich zu beheben, damit ich MySQL mit meiner eigenen Version von ZLIB kompilieren kann (anstatt mit der mitgelieferten Version):

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

Voila!

dcarrith
quelle
60
Danke, das war hilfreich. Für andere, die gcc zum Kompilieren und Verknüpfen ihres Programms verwenden (anstatt ld direkt zu verwenden), können Sie -Xlinker --verboseden Befehlszeilenargumenten von gcc hinzufügen , damit diese Option an ld übergeben wird.
5
Das hat mir auch geholfen. Das Makefile, das ich hatte, erwartete nur statische Bibliotheken, also wurde es verwendet -Wl,-Bstatic. Dies beschränkt die Suche nur auf .a-Dateien. Die ausführliche Option zeigte dies deutlich. Nach dem Entfernen -Wl,-Bstaticwurden auch gemeinsam genutzte Bibliotheken durchsucht.
Micah94
2
Ich bin auf FreeBSD 10. Der neue LLVM Clang cc nimmt ein Argument der Form -Wl,--verboseund geht --verbosean den Linker.
Christian Campbell
7
Das nenne ich eine perfekte Antwort! Vielen Dank. Das hat viel Zeit gespart. Nur um jemandem wie mir zu helfen. Es kann auch zum Debuggen von pfadbezogenen Problemen verwendet werden. Stellen Sie sicher, dass Sie den Pfad mit -L <Pfad zum Verzeichnis> mit dem Befehl ld -L <Pfad> -l <Bibliotheksname> --verbose
sbhatt
2
@ EdwardBlack Siehe diese Antwort . Fügen Sie für gcc im Wesentlichen einfach hinzu -Wl,--verbose, um den Linker ausführlich zu übergeben.
Chembrad
46

Es scheint keine Antwort zu geben, die das sehr häufige Anfängerproblem behebt, die erforderliche Bibliothek überhaupt nicht zu installieren.

Wenn auf Debianish-Plattformen libfooetwas fehlt, können Sie es häufig mit etwas wie installieren

apt-get install libfoo-dev

Die -devVersion des Pakets wird für Entwicklungsarbeiten benötigt, auch für triviale Entwicklungsarbeiten wie das Kompilieren von Quellcode zur Verknüpfung mit der Bibliothek.

Der Paketname erfordert manchmal einige Dekorationen ( libfoo0-dev? foo-devOhne das libPräfix? Usw.), oder Sie können einfach Ihre Distributionen verwenden Paket suchen genau , um herauszufinden , welche Pakete eine bestimmte Datei zur Verfügung stellen.

(Wenn es mehr als eine gibt, müssen Sie herausfinden, wo ihre Unterschiede liegen. Die Auswahl der coolsten oder beliebtesten ist eine häufige Abkürzung, aber kein akzeptables Verfahren für ernsthafte Entwicklungsarbeiten.)

Für andere Architekturen (insbesondere RPM) gelten ähnliche Verfahren, obwohl die Details unterschiedlich sind.

Tripleee
quelle
3
Dies hat mir nur bei einem Problem geholfen, das ich mit einem neuen Server und Perl hatte. apt-get install libperl-devsortierte es für mich. Danke :)
Andrew Newby
1
Diese! Keine Notwendigkeit, sich mit dem Makefile
Byron Whitlock
Dies ist wahrscheinlich die häufigste Lösung und hat mir geholfen, Cacti-Spine unter CentOS 7 zu kompilieren. Eine einfache yum install openssl-develLösung.
Djluko
1
Dies ist die beste Lösung, wenn Sie feststellen, dass der Symlink mit der Endung .so fehlt, Sie jedoch einen Symlink wie libfoo.so.6 -> libfoo.so.6.0.2 (zum Beispiel) haben, anstatt den Symlink mit zu erstellen Hand. (Das heißt, Sie haben das Paket libfoo installiert, aber nicht libfoo-dev)
dmaestro12
39

Kompilierungszeit

Wenn g ++ sagt cannot find -l<nameOfTheLibrary>, bedeutet dies, dass g ++ nach der Datei gesucht lib{nameOfTheLibrary}.sohat, sie jedoch nicht im Suchpfad der gemeinsam genutzten Bibliothek gefunden hat, der standardmäßig auf /usr/libund /usr/local/libund woanders verweist .

Um dieses Problem zu beheben, sollten Sie entweder die Bibliotheksdatei ( lib{nameOfTheLibrary}.so) in diesen Suchpfaden angeben oder die -LBefehlsoption verwenden. -L{path}Weist das g ++ (tatsächlich ld) an, {path}zusätzlich zu den Standardpfaden Bibliotheksdateien im Pfad zu finden .

Beispiel: Angenommen, Sie haben eine Bibliothek unter /home/taylor/libswift.sound möchten Ihre App mit dieser Bibliothek verknüpfen. In diesem Fall sollten Sie g ++ mit folgenden Optionen versorgen:

g++ main.cpp -o main -L/home/taylor -lswift
  • Hinweis 1 : Mit der -lOption wird der Bibliotheksname ohne lib und .soam Anfang und Ende abgerufen.

  • Hinweis 2 : In einigen Fällen folgt auf den Namen der Bibliotheksdatei beispielsweise die Version libswift.so.1.2. In diesen Fällen kann g ++ auch die Bibliotheksdatei nicht finden. Eine einfache Problemumgehung, um dies zu beheben, besteht darin, eine symbolische Verknüpfung zu libswift.so.1.2aufgerufen zu erstellen libswift.so.


Laufzeit

Wenn Sie Ihre App mit einer gemeinsam genutzten Bibliothek verknüpfen, muss die Bibliothek immer verfügbar sein, wenn Sie die App ausführen. Zur Laufzeit sucht Ihre App (eigentlich dynamischer Linker) nach ihren Bibliotheken in LD_LIBRARY_PATH. Es ist eine Umgebungsvariable, die eine Liste von Pfaden speichert.

Beispiel: Bei unserem libswift.soBeispiel kann dynamische Linker nicht finden libswift.soinLD_LIBRARY_PATH (der auf Standard - Suchpfade). Um das Problem zu beheben, sollten Sie diese Variable an den Pfad anhängen, in dem sie sich libswift.sobefindet.

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/taylor
Frogatto
quelle
Danke für deinen Beitrag! Ich habe alle Antworten ignoriert, bis ich .soDateien kopiert habe /usr/lib, aber es wurde für mich interessant, ob exportes helfen wird. Trotz makelängerer Installation trat ein weiterer Fehler auf. Dieses Mal wurde die .so.0Datei nicht gefunden, aber beide .sound die .so.0Datei befanden sich in dem Verzeichnis, in dem ich ein abhängiges Paket aus dem Quellcode erstellt habe. Könnten Sie dabei helfen?
A.Ametov
33

Während der Kompilierung mit g++via makedefinieren, LIBRARY_PATHob es möglicherweise nicht angebracht ist, das Makefile mit der -LOption zu ändern . Ich hatte meine zusätzliche Bibliothek eingerichtet, /opt/libalso tat ich:

$ export LIBRARY_PATH=/opt/lib/

und lief dann makefür eine erfolgreiche Kompilierung und Verknüpfung.

Um das Programm mit einer gemeinsam genutzten Bibliothek auszuführen, definieren Sie:

$ export LD_LIBRARY_PATH=/opt/lib/

vor dem Ausführen des Programms.

Finn Årup Nielsen
quelle
14

Zunächst müssen Sie die Namensregel kennen von lxxx:

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

lcbedeutet libc.so, lltdlbedeutet libltdl.so, lXtstbedeutet libXts.so.

Es ist also lib+ lib-name+.so


Sobald wir den Namen kennen, können wir locateden Pfad dieser lxxx.soDatei finden.

$ 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

Wenn Sie es nicht finden können, müssen Sie es mit installieren yum(ich verwende CentOS). Normalerweise haben Sie diese Datei, aber sie ist nicht mit der richtigen Stelle verknüpft.


Verknüpfe es mit dem richtigen Ort, normalerweise ist es /lib64oder/usr/lib64

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

Erledigt!

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

Belter
quelle
4
locateFunktioniert nur, wenn es regelmäßig installiert ist und ausgeführt wird. Eine grobe Problemumgehung besteht darin, findauf Ihrer gesamten Festplatte ausgeführt zu werden, aber es wird natürlich einige Zeit dauern. Wenn Sie dies häufig tun, sollten Sie eine Installation locatein Betracht ziehen, um die (interaktiven, menschlichen) Kosten dieses Vorgangs zu senken.
Tripleee
5

Wenn Sie Ihr Programm kompilieren, müssen Sie den Pfad zur Bibliothek angeben. Verwenden Sie in g ++ die Option -L:

g++ myprogram.cc -o myprogram -lmylib -L/path/foo/bar
Koan
quelle
1
Welche Eigenschaft müssen wir ändern, ccmakedamit die Makefilemit dem verknüpften Flag erstellt wird? Ich möchte meine -lARToolkitPlusFlagge mit einem Pfad verknüpfen .
Shashwat
2

Dieser Fehler kann auch auftreten, wenn sich die symbolische Verknüpfung zu einer dynamischen Bibliothek befindet, aber aus älteren Gründen -staticunter den Verknüpfungsflags angezeigt wird . Wenn ja, entfernen Sie es.

Vzbux
quelle
2

Überprüfen Sie den Speicherort Ihrer Bibliothek, z. B. lxxx.so:

locate lxxx.so

Wenn es sich nicht im /usr/libOrdner befindet, geben Sie Folgendes ein:

sudo cp yourpath/lxxx.so /usr/lib

Erledigt.

hua
quelle
4
Beim Kopieren von Bibliotheken in Systemverzeichnisse ist Vorsicht geboten.
Paul Floyd
2

Abgesehen von den bereits gegebenen Antworten kann es auch vorkommen, dass die Datei * .so vorhanden ist, aber nicht richtig benannt ist. Oder es kann vorkommen, dass die Datei * .so vorhanden ist, aber einem anderen Benutzer / Root gehört.

Problem 1: Falscher Name

Wenn Sie die Datei wie -l<nameOfLibrary> folgt verknüpfen, MUSS der Name der Bibliotheksdatei die Form haben. lib<nameOfLibrary> Wenn Sie nur eine <nameOfLibrary>.soDatei haben, benennen Sie diese um!

Ausgabe 2: Falscher Besitzer

Um zu überprüfen, ob dies nicht das Problem ist, gehen Sie wie folgt vor

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

Wenn die Datei Root oder einem anderen Benutzer gehört, müssen Sie dies tun

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

Die Bibliothek, mit der ich eine Verknüpfung herstellen wollte, hatte einen nicht standardmäßigen Namen (dh es wurde kein 'lib' vorangestellt). Daher wurde empfohlen, einen solchen Befehl zum Kompilieren zu verwenden.

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

Brian Burns
quelle
Nur mit dem
Präfix
1

Hier sind Ubuntu-Informationen zu meinem Laptop.

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

Ich benutze find, um die .so-Dateien für boost_filesystem und boost_system zu finden

locate libboost_filesystem
locate libboost_system

Verknüpfen Sie dann .so-Dateien mit / usr / lib und benennen Sie sie in .so um

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

Erledigt! R-Paket velocyto.R wurde erfolgreich installiert!

Shicheng Guo
quelle
1

Ich habe die gleiche Fehlermeldung festgestellt.

Ich habe das cmockaals erstellt sound versucht, es mit meiner ausführbaren Datei zu verknüpfen. Aber ldbeschwert sich immer unten:

/ usr / bin / ld: -lcmocka kann nicht gefunden werden

Es stellt sich heraus, dass nach dem Erstellen 3 Dateien generiert cmockawurden:

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

1 und 2 sind Symbolverknüpfungen und nur 3 ist die echte Datei.

Ich habe nur die 1 in meinen Bibliotheksordner kopiert, wo ich lddie 3 nicht finden konnte.

Nachdem ich alle 3 kopiert habe, ldfunktioniert.

smwikipedia
quelle
Können Sie bitte sagen, welchen Ordner Sie unter "Mein Bibliotheksordner" meinen?
A.Ametov