usr / bin / ld: no se puede encontrar -l <nameOfTheLibrary>

443

Estoy tratando de compilar mi programa y me devuelve este error:

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

en mi archivo MAKE utilizo el comando g++y el enlace a mi biblioteca, que es un enlace simbólico a mi biblioteca ubicado en otro directorio.

¿Hay una opción para agregar para que funcione, por favor?

ZoOo
fuente
1
Necesito más información ¿Qué comando emitiste para compilar tu programa? Puedes usar make -n-your-target para que make simplemente imprima los comandos que normalmente invocaría
djf
Publique el archivo MAKE o el comando que ejecute.
Ortwin Angermeier
mi comando es este: g ++ - <options> objetc1.o objetc2.o objetc3.o objetc4.o -L <pathOfTheLibrary> -l <nameOfTheLibrary> -lpthread -o myexe
ZoOo
44
¿La biblioteca con la que desea vincular está construida con la misma arquitectura (por ejemplo, 32/64 bits)? ¿La biblioteca que desea vincular con una biblioteca personalizada? El nombre de la biblioteca es importante, ya que debe comenzar con lib <nombre> cuando se usa el -lmodificador (por ejemplo, libpthread.so ya se está vinculando).
Ortwin Angermeier
1
¡El problema estaba en mi enlace simbólico en la biblioteca que no era bueno! Gracias por tu ayuda !
ZoOo

Respuestas:

196

Si el nombre de su biblioteca es decir libxyz.soy se encuentra en la ruta, diga:

/home/user/myDir

luego para vincularlo a su programa:

g++ -L/home/user/myDir -lxyz myprog.cpp -o myprog
Saurabh Bhola
fuente
11
mi biblioteca no es dinámica (.so) sino estática (.a). ¿El problema viene de eso?
ZoOo
3
@ZoOo que normalmente no debería importar, el enlazador puede funcionar con cualquiera de ellos
djf
77
Otra forma de vincular su biblioteca es que puede especificar directamente el nombre de la biblioteca con la ruta completa, como g ++ .. /path/mylib.a
Saurabh Bhola
2
Sí, pero aún no funciona. Mi biblioteca es un enlace simbólico, ¡creo que el problema proviene de eso porque cuando uso la biblioteca en el otro directorio funciona!
ZoOo
2
¿Su enlace simbólico apunta correctamente a la biblioteca en la ubicación real? ¿Puede publicar la salida de "ll" en el enlace simbólico.
Saurabh Bhola
451

Para averiguar qué está buscando el vinculador, ejecútelo en modo detallado.

Por ejemplo, me encontré con este problema al intentar compilar MySQL con soporte ZLIB. Recibí un error como este durante la compilación:

/usr/bin/ld: cannot find -lzlib

Busqué en Google y seguí encontrando diferentes problemas del mismo tipo en los que la gente decía para asegurarse de que el archivo .so realmente existe y, si no es así, crear un enlace simbólico al archivo versionado, por ejemplo, zlib. so.1.2.8. Pero, cuando verifiqué, zlib.so existía. Entonces, pensé, seguramente ese no podría ser el problema.

Encontré otra publicación en Internet que sugería ejecutar make con LD_DEBUG = all:

LD_DEBUG=all make

Aunque obtuve una TONELADA de salida de depuración, en realidad no fue útil. Agregó más confusión que cualquier otra cosa. Entonces, estaba a punto de rendirme.

Entonces, tuve una epifanía. Pensé en verificar el texto de ayuda para el comando ld:

ld --help

A partir de eso, descubrí cómo ejecutar ld en modo detallado (imagine eso):

ld -lzlib --verbose

Este es el resultado que obtuve:

==================================================
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 finalmente arreglarlo y poder 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!

dcarrith
fuente
6060
Gracias, esto fue útil. Para otros que usan gcc para compilar y vincular su programa (en lugar de usar ld directamente), puede agregar -Xlinker --verbosea los argumentos de la línea de comandos de gcc para que pase esta opción a ld.
55
Esto también me ayudó. El Makefile que tenía solo esperaba bibliotecas estáticas, así que lo usé -Wl,-Bstatic. Esto limita la búsqueda a archivos .a solamente. La opción detallada mostró esto claramente. Una vez que eliminé -Wl,-Bstaticlas bibliotecas compartidas también se buscaron.
micah94
2
Estoy en FreeBSD 10. El nuevo LLVM Clang cc toma un argumento del formulario -Wl,--verbosey lo pasa --verboseal enlazador.
Christian Campbell
77
¡Eso es lo que yo llamo una respuesta perfecta! Muchas gracias. Se ahorró mucho tiempo. Solo para agregar para ayudar a alguien como yo. También se puede usar para depurar problemas relacionados con la ruta. Asegúrese de verificar la ruta con -L <ruta al directorio> con el comando, ld -L <ruta> -l <nombre de biblioteca> --verbose
sbhatt 9/15
2
@EdwardBlack Mira esta respuesta . Esencialmente, para gcc, solo agregue -Wl,--verbosepara pasar de forma detallada al enlazador.
Chembrad
46

No parece haber ninguna respuesta que aborde el problema muy común para principiantes de no instalar la biblioteca requerida en primer lugar.

En las plataformas Debianish, si libfoofalta, puede instalarlo frecuentemente con algo como

apt-get install libfoo-dev

La -devversión del paquete es necesaria para el trabajo de desarrollo, incluso el trabajo de desarrollo trivial, como compilar el código fuente para vincular a la biblioteca.

El nombre del paquete a veces requerirá algunas decoraciones ( libfoo0-dev? foo-devSin el libprefijo? Etc.), o simplemente puede usar la búsqueda de paquetes de su distribución para averiguar con precisión qué paquetes proporcionan un archivo en particular.

(Si hay más de uno, necesitará averiguar cuáles son sus diferencias. Elegir el mejor o el más popular es un atajo común, pero no es un procedimiento aceptable para cualquier trabajo de desarrollo serio).

Para otras arquitecturas (más notablemente RPM) se aplican procedimientos similares, aunque los detalles serán diferentes.

tripleee
fuente
3
Esto me ayudó con un problema que estaba teniendo con un servidor nuevo y Perl. apt-get install libperl-devLo resolvió para mí. Gracias :)
Andrew Newby
1
¡Esta! No es necesario meterse con el Makefile
Byron Whitlock
Esta es probablemente la solución más común y me ayudó a compilar cacti-spine en CentOS 7. Una yum install openssl-develsolución simple .
djluko
1
Esta es la mejor solución si encuentra que falta el enlace simbólico que termina en .so, pero tiene un enlace simbólico como libfoo.so.6 -> libfoo.so.6.0.2 (por ejemplo), en lugar de crear el enlace simbólico por mano. (lo que significa que tiene el paquete libfoo instalado, pero no libfoo-dev)
dmaestro12
39

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/liby /usr/local/libquizás en otro lugar.

Para resolver este problema, debe proporcionar el archivo de biblioteca ( lib{nameOfTheLibrary}.so) en esas rutas de búsqueda o usar la -Lopción de comando. -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 /home/taylor/libswift.soy desea vincular su aplicación a esta biblioteca. En este caso, debe proporcionar el g ++ con las siguientes opciones:

g++ main.cpp -o main -L/home/taylor -lswift
  • Nota 1 : la -lopción obtiene el nombre de la biblioteca sin lib y .soal 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 biblioteca. Una solución simple para solucionar esto es crear un enlace simbólico a libswift.so.1.2llamado libswift.so.


Tiempo de ejecución

Cuando vincula su aplicación a una biblioteca compartida, se requiere que la biblioteca permanezca disponible siempre que ejecute la aplicación. En tiempo de ejecución, su aplicación (en realidad vinculador 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 libswift.soejemplo, el enlazador dinámico no puede encontrar libswift.soen LD_LIBRARY_PATH(que apunta a rutas de búsqueda predeterminadas). Para solucionar el problema, debe agregar esa variable con la ruta libswift.so.

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/taylor
frogatto
fuente
Gracias por tu publicación! He estado ignorando todas las respuestas hasta el momento en que copié los .soarchivos /usr/lib, pero me resultó interesante si exportayudaría. A pesar del proceso de instalación después de makecontinuar por más tiempo, se produjo otro error. Esta vez, .so.0no se encontró el archivo, pero ambos .soy el .so.0archivo estaban en el directorio donde he compilado el paquete dependiente desde la fuente. ¿Podrías ayudar con eso?
A.Ametov
33

Durante la compilación con g++ via makedefine LIBRARY_PATHsi puede no ser apropiado cambiar el Makefile con la -Lopción. Había puesto mi biblioteca extra, /opt/libasí que hice:

$ export LIBRARY_PATH=/opt/lib/

y luego se postuló makepara una compilación y vinculación exitosa.

Para ejecutar el programa con una biblioteca compartida, defina:

$ export LD_LIBRARY_PATH=/opt/lib/

antes de ejecutar el programa.

Finn Årup Nielsen
fuente
14

Primero, debe 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

lcsignifica libc.so, lltdlsignifica libltdl.so, lXtstsignifica libXts.so.

Entonces, es lib+ lib-name+.so


Una vez que sepamos el nombre, podemos usarlo locatepara encontrar la ruta de este lxxx.soarchivo.

$ 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 yum(uso CentOS). Por lo general, tiene este archivo, pero no se vincula al lugar correcto.


Vincúlelo al lugar correcto, generalmente es /lib64o/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

Belter
fuente
44
locatesolo funciona si está instalado y funcionando regularmente. Una solución alternativa es ejecutarlo finden todo el disco, pero, por supuesto, llevará tiempo. Si se encuentra haciendo eso con frecuencia, considere instalarlo locatesolo para reducir el costo (interactivo, humano) de esta operación.
tripleee
5

Cuando compila su programa, debe proporcionar la ruta a la biblioteca; en g ++ use la opción -L:

g++ myprogram.cc -o myprogram -lmylib -L/path/foo/bar
koan
fuente
1
¿Qué propiedad tenemos que cambiar ccmakepara que Makefilese cree con la bandera vinculada? Quiero vincular mi -lARToolkitPlusbandera a un camino.
Shashwat
2

Este error también puede producirse si el enlace simbólico es a una biblioteca dinámica, .so, pero por razones heredadas -staticaparece entre los indicadores de enlace. Si es así, intente eliminarlo.

Vzbux
fuente
2

Verifique la ubicación de su biblioteca, por ejemplo lxxx.so:

locate lxxx.so

Si no está en la /usr/libcarpeta, escriba esto:

sudo cp yourpath/lxxx.so /usr/lib

Hecho.

Hua
fuente
44
Debe tener cuidado al copiar bibliotecas en los directorios del sistema.
Paul Floyd
2

Además de las respuestas ya dadas, también puede darse el caso de que el archivo * .so exista pero no tenga un nombre adecuado. O puede ser que el archivo * .so exista pero que sea propiedad de otro usuario / root.

Problema 1: nombre incorrecto

Si está vinculando el archivo, -l<nameOfLibrary> entonces el nombre del archivo de la biblioteca DEBE tener la forma. lib<nameOfLibrary> Si solo tiene un <nameOfLibrary>.soarchivo, cámbiele el nombre.

Problema 2: propietario incorrecto

Para verificar que este no sea el problema, haga

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
usuario13107
fuente
1

La biblioteca a la que intentaba vincular resultó tener un nombre no estándar (es decir, no tenía el prefijo 'lib'), por lo que me recomendaron usar un comando como este para compilarlo:

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

Brian Burns
fuente
Solo prefijo "lib" para obtener un nombre estándar que me lo
arregló
1

Aquí está la información de Ubuntu de mi computadora portátil.

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

Utilizo localizar para encontrar los archivos .so para boost_filesystem y boost_system

locate libboost_filesystem
locate libboost_system

Luego vincule los archivos .so a / usr / lib y cambie el nombre a .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

¡Hecho! El paquete R velocyto.R se instaló correctamente.

Shicheng Guo
fuente
1

Encontré el mismo mensaje de error.

Construí el cmockacomo a soe intenté vincularlo a mi ejecutable. Pero ldsiempre se queja a continuación:

/ usr / bin / ld: no se puede encontrar -lcmocka

Resulta que hay 3 archivos generados después de que cmockase genera :

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

1 y 2 son enlaces de símbolos y solo 3 es el archivo real.

Solo copié el 1 en la carpeta de mi biblioteca, donde ldno pude encontrar el 3.

Después de copiar los 3, ldfunciona.

smwikipedia
fuente
¿Puedes decir por favor a qué carpeta te refieres bajo "mi carpeta de biblioteca"?
A.Ametov