Ich versuche mein Programm zu kompilieren und es wird folgende Fehlermeldung ausgegeben:
usr/bin/ld: cannot find -l<nameOfTheLibrary>
in meinem Makefile verwende ich den Befehl g++
und einen Link zu meiner Bibliothek, die einen symbolischen Link zu meiner Bibliothek in einem anderen Verzeichnis darstellt.
Gibt es eine Option zum Hinzufügen, damit es funktioniert?
Wenn Ihr Bibliotheksname libxyz.so
lautet und sich im 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
Um herauszufinden, wonach der Linker sucht, führen Sie ihn im ausführlichen Modus aus.
Ich bin zum Beispiel auf dieses Problem gestoßen, als ich versuchte, MySQL mit ZLIB-Unterstützung zu kompilieren. Ich habe beim Kompilieren eine solche Fehlermeldung erhalten:
/usr/bin/ld: cannot find -lzlib
Ich habe ein paar Googl'ing-Aktionen durchgeführt und bin immer wieder auf Probleme mit der gleichen Art gestoßen, in denen die Leute sagten, um sicherzustellen, dass die .so-Datei tatsächlich existiert. Falls nicht, erstellen Sie einen Symlink zu der versionierten Datei, z. so.1.2.8. Wenn ich jedoch einen Haken habe, existiert zlib.so DID. Also, dachte ich, das könnte doch nicht das Problem sein.
Ich habe einen anderen Post auf dem Internet gefunden, der vorschlug, make mit LD_DEBUG = all auszuführen:
LD_DEBUG=all make
Obwohl ich eine Menge an Debugging-Ausgaben bekam, war das eigentlich nicht hilfreich. Es fügte mehr Verwirrung hinzu als alles andere. Also wollte ich aufgeben.
Dann hatte ich eine Epiphanie. Ich dachte eigentlich, den Hilfetext für den Befehl ld zu überprüfen:
ld --help
Daraus habe ich herausgefunden, wie ich ld im ausführlichen Modus ausführen kann (stellen Sie sich das vor):
ld -lzlib --verbose
Dies ist die Ausgabe, die ich bekam:
==================================================
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 endgültig 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!
Definieren Sie g++
während der Kompilierung mit LIBRARY_PATH
über make
, wenn es nicht angebracht ist, das Makefile mit der -L
-Option zu ändern. Ich hatte meine zusätzliche Bibliothek in /opt/lib
gestellt, also habe ich:
$ export LIBRARY_PATH=/opt/lib/
und dann make
für erfolgreiches Kompilieren und Verknüpfen.
Um das Programm mit einer gemeinsam genutzten Bibliothek auszuführen, definieren Sie Folgendes:
$ export LD_LIBRARY_PATH=/opt/lib/
bevor Sie das Programm ausführen.
Es scheint keine Antwort zu geben, die auf das sehr häufige Problem des Anfängers eingeht, die erforderliche Bibliothek überhaupt nicht zu installieren.
Wenn auf Debianish-Plattformen libfoo
fehlt, können Sie es häufig mit etwas installieren
apt-get install libfoo-dev
Die -dev
-Version des Pakets ist für die Entwicklungsarbeit erforderlich, selbst für triviale Entwicklungsarbeiten wie das Kompilieren von Quellcode für die Verknüpfung mit der Bibliothek.
Für den Paketnamen sind manchmal einige Dekorationen erforderlich (libfoo0-dev
? foo-dev
ohne Präfix lib
? Usw.), oder Sie können einfach die package search -Distribution Ihrer Distribution verwenden, um herauszufinden, welche Pakete eine bestimmte Datei enthalten.
(Wenn es mehr als eine gibt, müssen Sie herausfinden, welche Unterschiede es gibt. Die Auswahl der coolsten oder beliebtesten ist eine übliche Abkürzung, aber kein akzeptables Verfahren für eine ernsthafte Entwicklungsarbeit.)
Für andere Architekturen (insbesondere RPM) gelten ähnliche Verfahren, die Details sind jedoch unterschiedlich.
Wenn G ++ cannot find -l<nameOfTheLibrary>
sagt, bedeutet dies, dass G ++ nach der Datei lib{nameOfTheLibrary}.so
gesucht hat, diese aber nicht im Suchpfad der gemeinsam genutzten Bibliothek gefunden wurde, was standardmäßig auf /usr/lib
und /usr/local/lib
und irgendwo anders hinweist.
Um dieses Problem zu beheben, sollten Sie entweder die Bibliotheksdatei (lib{nameOfTheLibrary}.so
) in diesen Suchpfaden angeben oder die Befehlsoption -L
verwenden. -L{path}
weist das G ++ (eigentlich ld
) an, zusätzlich zu den Standardpfaden Bibliotheksdateien im Pfad {path}
zu suchen.
Beispiel: Angenommen, Sie haben eine Bibliothek unter /home/taylor/libswift.so
und möchten Ihre App mit dieser Bibliothek verknüpfen. In diesem Fall sollten Sie den G++
mit den folgenden Optionen angeben:
g++ main.cpp -o main -L/home/taylor -lswift
Hinweis 1 : -l
-Option ruft den Bibliotheksnamen ohnelib
und .so
am Anfang und Ende ab.
Hinweis 2 : In einigen Fällen folgt auf den Namen der Bibliotheksdatei deren Version, beispielsweise libswift.so.1.2
. In diesen Fällen kann G ++ auch die Bibliotheksdatei nicht finden. Eine einfache Problemumgehung besteht darin, einen symbolischen Link zu libswift.so.1.2
mit dem Namen libswift.so
zu erstellen.
Wenn Sie Ihre App mit einer gemeinsam genutzten Bibliothek verknüpfen, muss die Bibliothek immer verfügbar bleiben, wenn Sie die App ausführen. Zur Laufzeit sucht Ihre App (eigentlich dynamischer Linker) in LD_LIBRARY_PATH
nach ihren Bibliotheken. Es ist eine Umgebungsvariable, die eine Liste von Pfaden speichert.
Beispiel: Im Fall unseres libswift.so
-Beispiels kann der dynamische Linker libswift.so
nicht in LD_LIBRARY_PATH
finden (was auf Standardsuchpfade verweist). Um das Problem zu beheben, sollten Sie diese Variable mit dem Pfad libswift.so
anhängen.
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/taylor
Zuerst müssen Sie die Namensregel von lxxx
kennen:
/usr/bin/ld: cannot find -lc
/usr/bin/ld: cannot find -lltdl
/usr/bin/ld: cannot find -lXtst
lc
bedeutet libc.so
, lltdl
bedeutet libltdl.so
, lXtst
bedeutet libXts.so
.
Es ist also lib
+ lib-name
+ .so
Sobald wir den Namen kennen, können wir locate
verwenden, um den Pfad dieser lxxx.so
-Datei zu 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 yum
(ich verwende CentOS) installieren. Normalerweise haben Sie diese Datei, aber sie ist nicht an den richtigen Ort verlinkt.
Verknüpfe es mit der richtigen Stelle, normalerweise /lib64
oder /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
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
Überprüfen Sie den Speicherort Ihrer Bibliothek, zum Beispiel lxxx.so:
locate lxxx.so
Wenn es sich nicht im Ordner /usr/lib
befindet, geben Sie Folgendes ein:
Sudo cp yourpath/lxxx.so /usr/lib
Erledigt.
Dieser Fehler kann auch hervorgerufen werden, wenn die symbolische Verknüpfung zu einer dynamischen Bibliothek besteht, .so aus à „kablen Gründen erscheint -static
unter den Verknüpfungsflags. Wenn ja, versuchen Sie es zu entfernen.
Abgesehen von den bereits gegebenen Antworten kann es auch vorkommen, dass die * .so-Datei existiert, aber nicht richtig benannt wird. Oder es kann der Fall sein, dass die * .so-Datei existiert, aber einem anderen Benutzer/root gehört.
Problem 1: Falscher Name
Wenn Sie die Datei als -l<nameOfLibrary>
Verknüpfen, MUSS der Name der Bibliotheksdatei die Form lib<nameOfLibrary>
.__ haben. Wenn Sie nur <nameOfLibrary>.so
-Datei haben, benennen Sie sie um!
Ausgabe 2: Falscher Besitzer
Um zu überprüfen, ob dies nicht das Problem ist - tun Sie es
ls -l /path/to/.so/file
Wenn die Datei im Besitz von root oder einem anderen Benutzer ist, müssen Sie dies tun
Sudo chown yourUserName:yourUserName /path/to/.so/file
Die Bibliothek, zu der ich eine Verknüpfung herstellen wollte, hatte einen nicht standardmäßigen Namen (d. H. Hatte kein 'lib'). Daher wurde empfohlen, einen Befehl wie diesen zu verwenden, um ihn zu kompilieren.
gcc test.c -Iinclude lib/cspice.a -lm
Mein Problem war, dass ich das übergeordnete Verzeichnis des von mir ausgeführten Programms umbenannt habe (mpicc
von MVAPICH) und die Binärdatei irgendwie beschädigt hat. Selbst das Voranstellen von LD_LIBRARY_PATH war nicht genug und ich musste es auf den richtigen Pfad neu kompilieren.
Hier ist Ubuntu Informationen von 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 locate, 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! Das R-Paket velocyto.R wurde erfolgreich installiert!