usr / bin/ ld: impossible de trouver-l
j'essaie de compiler mon programme et il retourne cette erreur :
usr/bin/ld: cannot find -l<nameOfTheLibrary>
dans mon makefile j'utilise la commande g++
et un lien vers ma bibliothèque qui est un lien symbolique vers ma bibliothèque située sur un autre répertoire.
y a-t-il une option à ajouter pour que cela fonctionne s'il vous plaît?
12 réponses
si votre nom de Bibliothèque est libxyz.so
et qu'il est situé sur le chemin, dites:
/home/user/myDir
puis le relier à votre programme:
g++ -L/home/user/myDir -lxyz myprog.cpp -o myprog
pour savoir ce que le linker cherche, lancez-le en mode verbose.
par exemple, j'ai rencontré ce problème en essayant de compiler MySQL avec le support ZLIB. Je recevais une erreur comme celle-ci lors de la compilation:
/usr/bin/ld: cannot find -lzlib
j'ai fait un peu de googling et continuais à venir à travers différentes questions du même genre où les gens diraient pour s'assurer le .donc le fichier existe réellement et s'il n'existe pas, alors créez un lien symbolique vers la version fichier, par exemple, zlib.alors?1.2.8. Mais, quand j'ai vérifié, zlib.donc il existait. Alors, j'ai pensé, sûrement, qui ne pouvait pas être le problème.
je suis tombé sur un autre post sur les Internets qui suggérait d'exécuter make avec LD_DEBUG=all:
LD_DEBUG=all make
bien que j'ai eu une tonne de sortie de débogage, ce n'était pas vraiment utile. Cela ajoutait plus de confusion que toute autre chose. Donc, j'étais sur le point d'abandonner.
puis, j'ai eu une révélation. J'ai pensé à en fait, vérifiez le texte d'aide pour la commande ld:
ld --help
A partir de là, j'ai compris comment exécuter ld en mode verbose (imaginez cela):
ld -lzlib --verbose
C'est la sortie que j'ai eu:
==================================================
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...
donc, pour finalement le corriger pour que je puisse compiler MySQL avec ma propre version de ZLIB (plutôt que la version empaquetée):
sudo ln -s /usr/lib/libz.so.1.2.8 /usr/lib/libzlib.so
voilà!
lors de la compilation avec g++
via make
définir LIBRARY_PATH
s'il n'est pas approprié de changer le Makefile avec l'option -L
. J'avais mis ma bibliothèque supplémentaire dans /opt/lib
alors j'ai fait:
$ export LIBRARY_PATH=/opt/lib/
puis a couru make
pour la compilation réussie et le lien.
Pour exécuter le programme avec une bibliothèque partagée définir:
$ export LD_LIBRARY_PATH=/opt/lib/
avant d'exécuter le programme.
il ne semble pas y avoir de réponse qui aborde le problème débutant très commun de ne pas installer la bibliothèque requise en premier lieu.
sur les plateformes Debianish, si libfoo
est manquant, vous pouvez souvent l'installer avec quelque chose comme
apt-get install libfoo-dev
la version -dev
du paquet est nécessaire pour le travail de développement, même le travail de développement trivial tel que la compilation du code source pour relier à la bibliothèque.
le nom du paquet nécessitera parfois des décorations ( libfoo0-dev
? foo-dev
sans le préfixe lib
? etc), ou vous pouvez simplement utiliser votre distro package search pour trouver précisément quels paquets fournissent un fichier particulier.
(S'il y en a plus d'un, vous devrez découvrir quelles sont leurs différences. Choisir le plus frais ou le plus populaire est un raccourci commun, mais pas un acceptable procédure pour tout travail de développement sérieux.)
pour d'autres architectures (notamment RPM) des procédures similaires s'appliquent, bien que les détails soient différents.
Compiler Time
quand G++ dit cannot find -l<nameOfTheLibrary>
, cela signifie que G++ a cherché le fichier lib{nameOfTheLibrary}.so
, mais il n'a pas pu le trouver dans le chemin de recherche de la bibliothèque partagée, qui par défaut pointe vers /usr/lib
et /usr/local/lib
et peut-être ailleurs.
pour résoudre ce problème, vous devez soit fournir le fichier de la bibliothèque ( lib{nameOfTheLibrary}.so
) dans ces chemins de recherche ou utiliser l'option de commande -L
. -L{path}
dit le G++ (en fait ld
) pour trouver les fichiers de bibliothèque dans le chemin {path}
en plus des chemins par défaut.
exemple: en supposant que vous avez une bibliothèque à /home/taylor/libswift.so
, et que vous voulez lier votre application à cette bibliothèque. Dans ce cas, vous devez fournir le G++
avec les options suivantes:
g++ main.cpp -o main -L/home/taylor -lswift
-
Note 1 :
-l
option obtient le nom de la bibliothèque sanslib
et.so
au début et à la fin. -
Note 2 : dans certains cas, le nom du fichier de la Bibliothèque est suivi de sa version, par exemple
libswift.so.1.2
. Dans ces cas, G++ ne peut pas non plus trouver le fichier de la bibliothèque. Une solution simple pour résoudre ce problème est de créer un lien symbolique verslibswift.so.1.2
appelélibswift.so
.
Runtime
Lorsque vous liez votre application à une bibliothèque partagée, il est nécessaire que la bibliothèque reste disponible chaque fois que vous exécutez l'application. Dans runtime votre application (en fait dynamic linker) cherche ses bibliothèques dans LD_LIBRARY_PATH
. C'est une variable d'environnement qui stocke une liste de chemins d'accès.
exemple: dans le cas de notre exemple libswift.so
, dynamic linker ne peut pas trouver libswift.so
dans LD_LIBRARY_PATH
(qui indique par défaut les chemins de recherche). Pour corriger le problème, vous devriez ajouter cette variable avec le chemin libswift.so
est dedans.
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/taylor
lorsque vous compilez votre programme, vous devez fournir le chemin d'accès à la bibliothèque; dans g++ utilisez l'option-L:
g++ myprogram.cc -o myprogram -lmylib -L/path/foo/bar
cette erreur peut aussi être provoquée si le lien symbolique est à une bibliothèque dynamique, .donc, mais pour des raisons d'héritage -static
apparaît parmi les drapeaux de lien. Si oui, essayez de le retirer.
tout d'abord, vous devez connaître la règle d'appellation de lxxx
:
/usr/bin/ld: cannot find -lc
/usr/bin/ld: cannot find -lltdl
/usr/bin/ld: cannot find -lXtst
lc
signifie libc.so
, lltdl
signifie libltdl.so
, lXtst
signifie libXts.so
.
donc, c'est lib
+ lib-name
+ .so
une fois que nous connaissons le nom, nous pouvons utiliser locate
pour trouver le chemin de ce fichier 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
si vous ne pouvez pas le trouver, vous devez l'installer par yum
(J'utilise CentOS). Habituellement, vous avez ce fichier, mais il ne se lie pas au bon endroit.
liez-le au bon endroit, Habituellement il est /lib64
ou /usr/lib64
$ sudo ln -s /home/user/anaconda3/lib/libiconv.so /usr/lib64/
fait!
ref: https://i-pogo.blogspot.jp/2010/01/usrbinld-cannot-find-lxxx.html
Vérifiez l'emplacement de votre bibliothèque, par exemple lxxx.so:
locate lxxx.so
si elle n'est pas dans le dossier /usr/lib
, tapez ceci:
sudo cp yourpath/lxxx.so /usr/lib
fait.
la bibliothèque que j'essayais de relier s'est avérée avoir un nom non standard (i.e. n'était pas préfixé avec 'lib'), donc ils ont recommandé d'utiliser une commande comme celle - ci pour la compiler -
gcc test.c -Iinclude lib/cspice.a -lm
outre les réponses déjà données, il se peut aussi que le *.donc le fichier existe mais n'est pas nommé correctement. Ou il peut être le cas que *.si le fichier existe, mais elle est détenue par un autre utilisateur / root.
Issue 1: Impropre name
si vous liez le fichier comme -l<nameOfLibrary>
alors le nom du fichier de la bibliothèque doit être du formulaire lib<nameOfLibrary>
Si vous n'avez que le fichier <nameOfLibrary>.so
, renommez-le!
Question 2: Mauvais propriétaire
Pour vérifier que ce n'est pas le problème - faire
ls -l /path/to/.so/file
si le fichier appartient à root ou à un autre utilisateur, vous devez faire
sudo chown yourUserName:yourUserName /path/to/.so/file
mon problème était que j'ai renommé le répertoire parent du programme que j'exécutais ( mpicc
de MVAPICH), et il a d'une certaine façon foiré le binaire. Même prepending LD_LIBRARY_PATH n'était pas suffisant et j'ai dû le recompiler sur le bon chemin.