c++ - compilar - usr/bin/ld: no se puede encontrar-l<nameOfTheLibrary>
g++ linux (12)
Estoy tratando de compilar mi programa y devuelve este error:
usr/bin/ld: cannot find -l<nameOfTheLibrary>
en mi makefile uso el comando g++
y el enlace a mi biblioteca, que es un enlace simbólico a mi biblioteca ubicada en otro directorio.
¿Hay alguna opción para agregar para que funcione por favor?
Tiempo de compilación
Cuando G ++ dice cannot find -l<nameOfTheLibrary>
, significa que G ++ buscó el archivo lib{nameOfTheLibrary}.so
, pero no pudo encontrarlo en la ruta de búsqueda de la biblioteca compartida, que por defecto apunta a /usr/lib
y /usr/local/lib
y en algún otro lugar tal vez.
Para resolver este problema, debe proporcionar el archivo de biblioteca ( lib{nameOfTheLibrary}.so
) en esas rutas de búsqueda o usar la opción de comando -L
. -L{path}
le dice a G ++ (en realidad ld
) que busque archivos de biblioteca en la ruta {path}
además de las rutas predeterminadas.
Ejemplo: Suponiendo que tiene una biblioteca en /home/taylor/libswift.so
, y desea vincular su aplicación a esta biblioteca. En este caso, debe suministrar a G++
las siguientes opciones:
g++ main.cpp -o main -L/home/taylor -lswift
Nota 1 : la opción
-l
obtiene el nombre de la biblioteca sinlib
y.so
al principio y al final.Nota 2 : en algunos casos, el nombre del archivo de la biblioteca va seguido de su versión, por ejemplo,
libswift.so.1.2
. En estos casos, G ++ tampoco puede encontrar el archivo de la biblioteca. Una solución sencilla para solucionar este problema es crear un enlace simbólico alibswift.so.1.2
llamadolibswift.so
.
Tiempo de ejecución
Cuando vincula su aplicación a una biblioteca compartida, es necesario que la biblioteca esté disponible siempre que ejecute la aplicación. En tiempo de ejecución, su aplicación (en realidad enlazador dinámico) busca sus bibliotecas en LD_LIBRARY_PATH
. Es una variable de entorno que almacena una lista de rutas.
Ejemplo: En el caso de nuestro ejemplo libswift.so
, el enlazador dinámico no puede encontrar libswift.so
en LD_LIBRARY_PATH
(que apunta a las rutas de búsqueda predeterminadas). Para solucionar el problema, debe agregar esa variable con la ruta libswift.so
está en.
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/taylor
Aparte de las respuestas ya dadas, también puede darse el caso de que el archivo * .so exista pero no tenga el nombre correcto. O puede ser el caso de que el archivo * .so exista, pero es propiedad de otro usuario / root.
Número 1: Nombre incorrecto
Si está vinculando el archivo como -l<nameOfLibrary>
, el nombre del archivo de la biblioteca DEBE tener la forma lib<nameOfLibrary>
Si solo tiene el <nameOfLibrary>.so
!
Número 2: propietario equivocado
Para verificar que este no es el problema - hacer
ls -l /path/to/.so/file
Si el archivo es propiedad de root u otro usuario, debe hacerlo
sudo chown yourUserName:yourUserName /path/to/.so/file
Cuando compile su programa, debe proporcionar la ruta a la biblioteca; en g ++ usa la opción -L:
g++ myprogram.cc -o myprogram -lmylib -L/path/foo/bar
Durante la compilación con g++
través de make
define LIBRARY_PATH
si es posible que no sea apropiado cambiar el Makefile con la opción -L
. Había puesto mi biblioteca extra en /opt/lib
así que hice:
$ export LIBRARY_PATH=/opt/lib/
y luego ejecutó make
para una compilación y enlace exitosos.
Para ejecutar el programa con una biblioteca compartida defina:
$ export LD_LIBRARY_PATH=/opt/lib/
Antes de ejecutar el programa.
Este error también puede producirse si el enlace simbólico es a una biblioteca dinámica, .so, pero por razones heredadas, la -static
aparece entre las banderas de enlace. Si es así, intente eliminarlo.
La biblioteca a la que intentaba enlazar resultó que tenía un nombre no estándar (es decir, no tenía el prefijo ''lib''), por lo que recomendaron usar un comando como este para compilarlo.
gcc test.c -Iinclude lib/cspice.a -lm
Mi problema fue que mpicc
el nombre del directorio principal del programa que estaba ejecutando ( mpicc
de MVAPICH), y de alguna manera me estropeó el binario. Incluso la preparación de LD_LIBRARY_PATH no fue suficiente y tuve que volver a compilarlo en la ruta correcta.
No parece haber ninguna respuesta que aborde el problema muy común de los principiantes de no instalar la biblioteca requerida en primer lugar.
En las plataformas Debianish, si falta libfoo
, puede instalarlo frecuentemente con algo como
apt-get install libfoo-dev
La versión -dev
del paquete es necesaria para el trabajo de desarrollo, incluso el trabajo de desarrollo trivial, como compilar el código fuente para vincularlo a la biblioteca.
El nombre del paquete a veces requerirá algunas decoraciones ( libfoo0-dev
? foo-dev
sin el prefijo lib
? Etc), o simplemente puede usar la búsqueda de paquetes de su distro para averiguar exactamente qué paquetes proporcionan un archivo en particular.
(Si hay más de uno, deberá averiguar cuáles son sus diferencias. Elegir lo mejor o lo más popular es un atajo común, pero no es un procedimiento aceptable para ningún trabajo de desarrollo serio).
Para otras arquitecturas (especialmente RPM) se aplican procedimientos similares, aunque los detalles serán diferentes.
Para averiguar lo que está buscando el enlazador, ejecútelo en modo detallado.
Por ejemplo, encontré este problema al intentar compilar MySQL con soporte de ZLIB. Recibí un error como este durante la compilación:
/usr/bin/ld: cannot find -lzlib
Hice algo de Googl''ing y seguí encontrando diferentes problemas del mismo tipo que la gente diría para asegurarse de que el archivo .so realmente existe y, en caso contrario, crear un enlace simbólico al archivo versionado, por ejemplo, zlib. así.1.2.8. Pero, cuando lo verifiqué, zlib.so DID existe. Entonces, pensé, seguramente ese no podría ser el problema.
Me encontré con otra publicación en Internet que sugería ejecutar make con LD_DEBUG = all:
LD_DEBUG=all make
Aunque obtuve TONELADAS de salida de depuración, en realidad no fue útil. Añadió más confusión que cualquier otra cosa. Por lo tanto, estaba a punto de rendirme.
Entonces, tuve una epifanía. Pensé en comprobar realmente el texto de ayuda para el comando ld:
ld --help
A partir de eso, descubrí cómo ejecutar ld en modo detallado (imagina que):
ld -lzlib --verbose
Esta es la salida que tengo:
==================================================
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 ...
Entonces, para solucionarlo finalmente, podría compilar MySQL con mi propia versión de ZLIB (en lugar de la versión incluida):
sudo ln -s /usr/lib/libz.so.1.2.8 /usr/lib/libzlib.so
Voila!
Primero, necesita conocer la regla de denominación de lxxx
:
/usr/bin/ld: cannot find -lc
/usr/bin/ld: cannot find -lltdl
/usr/bin/ld: cannot find -lXtst
lc
significa libc.so
, lltdl
significa libltdl.so
, lXtst
significa libXts.so
.
Entonces, es lib
+ lib-name
+ .so
Una vez que sepamos el nombre, podemos usar locate
para encontrar la ruta de este archivo 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 no puede encontrarlo, debe instalarlo por yum
(yo uso CentOS). Por lo general, tiene este archivo, pero no se vincula al lugar correcto.
/lib64
lugar correcto, generalmente es /lib64
o /usr/lib64
$ sudo ln -s /home/user/anaconda3/lib/libiconv.so /usr/lib64/
¡Hecho!
ref: https://i-pogo.blogspot.jp/2010/01/usrbinld-cannot-find-lxxx.html
Si el nombre de su biblioteca es decir libxyz.so
y está ubicado en la ruta, diga:
/home/user/myDir
Luego para enlazarlo a su programa:
g++ -L/home/user/myDir -lxyz myprog.cpp -o myprog
Verifique la ubicación de su biblioteca, por ejemplo lxxx.so:
locate lxxx.so
Si no está en la carpeta /usr/lib
, escriba esto:
sudo cp yourpath/lxxx.so /usr/lib
Hecho.