J'essaie de compiler mon programme et il renvoie cette erreur:
usr/bin/ld: cannot find -l<nameOfTheLibrary>
dans mon fichier makefile, j'utilise la commande g++
et un lien vers ma bibliothèque, qui est un lien symbolique vers ma bibliothèque située dans un autre répertoire.
Y at-il une option à ajouter pour le faire fonctionner s'il vous plaît?
Si votre nom de bibliothèque est dit libxyz.so
et qu'il se trouve sur le chemin, dites:
/home/user/myDir
puis pour le lier à votre programme:
g++ -L/home/user/myDir -lxyz myprog.cpp -o myprog
Pour savoir ce que l’éditeur de liens recherche, exécutez-le en mode commenté.
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 du Googl'ing et je n'arrêtais pas de rencontrer différents problèmes du même genre où les gens diraient de s'assurer que le fichier .so existait réellement. Sinon, créez un lien symbolique vers le fichier versionné, par exemple zlib. so.1.2.8. Mais, quand j'ai vérifié, zlib.so DID existe. Alors, j'ai pensé que ce ne pouvait sûrement pas être le problème.
Je suis tombé sur un autre article sur les internets qui suggérait de lancer make avec LD_DEBUG = all:
LD_DEBUG=all make
Bien que j'aie une tonne de sortie de débogage, ce n'était pas vraiment utile. Cela a ajouté plus de confusion qu'autre chose. Alors, j'étais sur le point d'abandonner.
Ensuite, j'ai eu une épiphanie. J'ai pensé vérifier le texte d'aide pour la commande ld:
ld --help
À partir de là, j'ai compris comment exécuter ld en mode verbose (imaginez cela):
ld -lzlib --verbose
Voici le résultat obtenu:
==================================================
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 résoudre le problème afin que je puisse compiler MySQL avec ma propre version de ZLIB (plutôt que la version fournie):
Sudo ln -s /usr/lib/libz.so.1.2.8 /usr/lib/libzlib.so
Voila!
Pendant la compilation avec g++
via make
, définissez LIBRARY_PATH
s'il ne convient pas de modifier le fichier 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/
et a ensuite lancé make
pour une compilation et une liaison réussies.
Pour exécuter le programme avec une bibliothèque partagée, définissez:
$ export LD_LIBRARY_PATH=/opt/lib/
avant d'exécuter le programme.
Il ne semble pas y avoir de réponse au problème très courant des débutants, à savoir l’installation de la bibliothèque requise en premier lieu.
Sur les plateformes Debianish, si libfoo
est manquant, vous pouvez l’installer fréquemment avec quelque chose comme:
apt-get install libfoo-dev
La version -dev
du package est requise pour les travaux de développement, même les travaux de développement les plus triviaux, tels que la compilation du code source destiné à être lié à la bibliothèque.
Le nom du paquet nécessitera parfois certaines décorations (libfoo0-dev
? foo-dev
sans le préfixe lib
? Etc), ou vous pouvez simplement utiliser la recherche package search de votre distribution pour trouver précisément quels packages fournissent un fichier particulier.
(S'il y en a plus d'un, vous devrez connaître leurs différences. Choisir le plus cool ou le plus populaire est un raccourci courant, mais pas une procédure acceptable pour un travail de développement sérieux.)
Pour les autres architectures (notamment RPM), des procédures similaires s'appliquent, bien que les détails soient différents.
Lorsque G ++ dit cannot find -l<nameOfTheLibrary>
, cela signifie que G ++ a recherché le fichier lib{nameOfTheLibrary}.so
, mais ne l'a pas trouvé dans le chemin de recherche de la bibliothèque partagée, qui pointe par défaut sur /usr/lib
et /usr/local/lib
et peut-être ailleurs.
Pour résoudre ce problème, vous devez soit fournir le fichier de bibliothèque (lib{nameOfTheLibrary}.so
) dans ces chemins de recherche, soit utiliser l'option de commande -L
. -L{path}
indique au G ++ (en fait, ld
) de rechercher 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 souhaitez 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 1L'option _: -l
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 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 bibliothèque. Une solution simple pour résoudre ce problème consiste à créer un lien symbolique vers libswift.so.1.2
appelé libswift.so
.
Lorsque vous liez votre application à une bibliothèque partagée, celle-ci doit rester disponible à chaque exécution de l'application. Au moment de l'exécution, votre application (éditeur de liens dynamique) recherche ses bibliothèques dans LD_LIBRARY_PATH
. C'est une variable d'environnement qui stocke une liste de chemins.
Exemple: Dans le cas de notre exemple libswift.so
, l'éditeur de liens dynamique ne trouve pas libswift.so
dans LD_LIBRARY_PATH
(qui pointe vers les chemins de recherche par défaut). Pour résoudre le problème, vous devez ajouter cette variable avec le chemin que libswift.so
est dans.
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/taylor
Tout d’abord, vous devez connaître la règle de nommage 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 le trouvez pas, vous devez l’installer par yum
(J'utilise CentOS). Habituellement, vous avez ce fichier, mais il n’est pas lié au bon endroit.
Associez-le au bon endroit, généralement /lib64
ou /usr/lib64
$ Sudo ln -s /home/user/anaconda3/lib/libiconv.so /usr/lib64/
Terminé!
ref: https://i-pogo.blogspot.jp/2010/01/usrbinld-cannot-find-lxxx.html
Lorsque vous compilez votre programme, vous devez fournir le chemin d'accès à la bibliothèque. en g ++, utilisez l'option -L:
g++ myprogram.cc -o myprogram -lmylib -L/path/foo/bar
Vérifiez l'emplacement de votre bibliothèque, par exemple, lxxx.so:
locate lxxx.so
Si ce n'est pas dans le dossier /usr/lib
, tapez ceci:
Sudo cp yourpath/lxxx.so /usr/lib
Terminé.
Cette erreur peut également se produire si le lien symbolique est vers une bibliothèque dynamique, .so, mais pour des raisons héritées, -static
apparaît parmi les indicateurs de lien. Si c'est le cas, essayez de l'enlever.
Outre les réponses déjà données, il se peut également que le fichier * .so existe mais qu'il ne soit pas nommé correctement. Ou bien le fichier * .so existe peut-être mais il appartient à un autre utilisateur/root.
Issue 1: Nom impropre
Si vous liez le fichier en tant que -l<nameOfLibrary>
, Le nom du fichier de bibliothèque DOIT être de la forme lib<nameOfLibrary>
Si vous ne possédez que le fichier <nameOfLibrary>.so
, renommez-le!
Numéro 2: Mauvais propriétaire
Pour vérifier que ce n’est pas le problème - faites
ls -l /path/to/.so/file
Si le fichier appartient à root ou à un autre utilisateur, vous devez le faire.
Sudo chown yourUserName:yourUserName /path/to/.so/file
La bibliothèque vers laquelle je tentais de créer un lien s’est révélée avoir un nom non standard (c’est-à-dire qu’elle n’était pas précédée de «lib»). Ils ont donc recommandé d’utiliser une commande comme celle-ci pour le compiler -
gcc test.c -Iinclude lib/cspice.a -lm
Mon problème était que j'ai renommé le répertoire parent du programme que j'exécutais (mpicc
de MVAPICH), ce qui a en quelque sorte gâché le fichier binaire. Même préparer LD_LIBRARY_PATH n'était pas suffisant et je devais le recompiler sur le chemin correct.
Voici les informations Ubuntu de mon ordinateur portable.
lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 18.04.2 LTS
Release: 18.04
Codename: bionic
J'utilise localiser pour trouver les fichiers .so pour boost_filesystem et boost_system
locate libboost_filesystem
locate libboost_system
Ensuite, liez les fichiers .so à/usr/lib et renommez-les en .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
Terminé! Le paquet R velocyto.R a été installé avec succès!