libpthread.so.0: error al agregar símbolos: falta DSO en la línea de comandos

205

Cuando estoy compilando openvswitch-1.5.0, he encontrado el siguiente error de compilación:

 gcc -Wstrict-prototypes -Wall -Wno-sign-compare -Wpointer-arith
     -Wdeclaration-after-statement -Wformat-security -Wswitch-enum -Wunused-parameter -Wstrict-aliasing -Wbad-function-cast -Wcast-align -Wstrict-prototypes -Wold-style-definition -Wmissing-prototypes -Wmissing-field-initializers -Wno-override-init  -g -O2 -export-dynamic ***-lpthread***  -o utilities/ovs-dpctl utilities/ovs-dpctl.o lib/libopenvswitch.a
 /home/jyyoo/src/dpdk/build/lib/librte_eal.a
 /home/jyyoo/src/dpdk/build/lib/libethdev.a
 /home/jyyoo/src/dpdk/build/lib/librte_cmdline.a
 /home/jyyoo/src/dpdk/build/lib/librte_hash.a
 /home/jyyoo/src/dpdk/build/lib/librte_lpm.a
 /home/jyyoo/src/dpdk/build/lib/librte_mbuf.a
 /home/jyyoo/src/dpdk/build/lib/librte_ring.a
 /home/jyyoo/src/dpdk/build/lib/librte_mempool.a
 /home/jyyoo/src/dpdk/build/lib/librte_malloc.a -lrt -lm 
     /usr/bin/ld: /home/jyyoo/src/dpdk/build/lib/librte_eal.a(eal.o): undefined reference
     to symbol 'pthread_create@@GLIBC_2.2.5'
     /lib/x86_64-linux-gnu/libpthread.so.0: error adding symbols: DSO missing from 
     command line

Si trato de ver los símbolos de libpthread, se ve bien.

$ readelf -s /lib/x86_64-linux-gnu/libpthread.so.0 | grep pthread_create
   199: 0000000000008220  2814 FUNC    GLOBAL DEFAULT   13 pthread_create@@GLIBC_2.2.5
   173: 0000000000008220  2814 FUNC    LOCAL  DEFAULT   13 __pthread_create_2_1
   462: 0000000000008220  2814 FUNC    GLOBAL DEFAULT   13 pthread_create@@GLIBC_2.2

¿Podría dar alguna pista o sugerencia?

jaeyong
fuente
link_libraries (pthread)
Alex Punnen
# readelf -s /lib/x86_64-linux-gnu/libncurses.so readelf: Error: No se pudo encontrar '/lib/x86_64-linux-gnu/libncurses.so'. Mensaje de error del sistema: Demasiados niveles de enlaces simbólicos
Ashish Karpe
Posible duplicado de DSO faltante en la línea de comando
luator
44
Maldita sea, yo gccnog++
Mensaje Auto

Respuestas:

164

Debe mencionar la biblioteca en la línea de comando después de que se compilen los archivos de objetos:

 gcc -Wstrict-prototypes -Wall -Wno-sign-compare -Wpointer-arith -Wdeclaration-after-statement -Wformat-security -Wswitch-enum -Wunused-parameter -Wstrict-aliasing -Wbad-function-cast -Wcast-align -Wstrict-prototypes -Wold-style-definition -Wmissing-prototypes -Wmissing-field-initializers -Wno-override-init \
     -g -O2 -export-dynamic -o utilities/ovs-dpctl utilities/ovs-dpctl.o \
     lib/libopenvswitch.a \
     /home/jyyoo/src/dpdk/build/lib/librte_eal.a /home/jyyoo/src/dpdk/build/lib/libethdev.a /home/jyyoo/src/dpdk/build/lib/librte_cmdline.a /home/jyyoo/src/dpdk/build/lib/librte_hash.a /home/jyyoo/src/dpdk/build/lib/librte_lpm.a /home/jyyoo/src/dpdk/build/lib/librte_mbuf.a /home/jyyoo/src/dpdk/build/lib/librte_ring.a /home/jyyoo/src/dpdk/build/lib/librte_mempool.a /home/jyyoo/src/dpdk/build/lib/librte_malloc.a \
     -lrt -lm -lpthread 

Explicación: la vinculación depende del orden de los módulos. Los símbolos se solicitan primero y luego se vinculan desde una biblioteca que los tiene. Por lo tanto, debe especificar los módulos que usan las bibliotecas primero y las bibliotecas después de ellos. Me gusta esto:

gcc x.o y.o z.o -la -lb -lc

Además, en caso de que haya una dependencia circular, debe especificar la misma biblioteca en la línea de comando varias veces. Entonces, en caso de que libbnecesite un símbolo libcy un libcsímbolo de libb, la línea de comando debería ser:

gcc x.o y.o z.o -la -lb -lc -lb
Michael Pankov
fuente
24
Creo que puedes hacerlo -Wl,--start-group -la -lb- -lc -Wl,--end-grouppara dependencias circulares.
Z boson
2
Tenga en cuenta que esto también se aplica a los archivos de origen: deben enumerarse antes de las bibliotecas. Puede pensar en los archivos de objetos resultantes que ocupan el lugar de los archivos de origen en la línea de comando y aplicar el mismo orden que el anterior.
jspencer
¿Dónde se debe agregar -lpthread cuando se usa make para compilar la aplicación?
codezombie
50

El mensaje de error depende de la versión de distribución / compilador:

Ubuntu Saucy:

/usr/bin/ld: /mnt/root/ffmpeg-2.1.1//libavformat/libavformat.a(http.o): undefined reference to symbol 'inflateInit2_'
/lib/x86_64-linux-gnu/libz.so.1: error adding symbols: DSO missing from command line

Ubuntu Raring: (más informativo)

/usr/bin/ld: note: 'uncompress' is defined in DSO /lib/x86_64-linux-gnu/libz.so.1 so try adding it to the linker command line

Solución: es posible que le falte una biblioteca en sus pasos de compilación, durante la etapa de vinculación. En mi caso, agregué '-lz' a las marcas de makefile / GCC.

Antecedentes: DSO es un objeto dinámico compartido o una biblioteca compartida.

kevinf
fuente
1
Utilicé esta solución para construir otro proyecto que estaba dando el mismo error al agregar -lz a LDFLAGS y funcionó perfectamente. ¡Gracias!
Mark Ellul
El error aún permanece para mí: / usr / bin / ld: gaSim.o: referencia indefinida al símbolo 'pthread_create @@ GLIBC_2.1' /lib/i386-linux-gnu/libpthread.so.0: error al agregar símbolos: DSO falta en la línea de comando
Aerox
En parte resuelto agregando '-lpthread', pero ahora me muestra: gaSim.c :(. Text + 0x11d6): referencia indefinida a 'glewInit'
Aerox
@Aerox: para glewInit, usted necesita-lGLEW
mchiasson
19

Antecedentes

los DSO missing from command line mensaje se mostrará cuando el vinculador no encuentre el símbolo requerido con su búsqueda normal, pero el símbolo está disponible en una de las dependencias de una biblioteca dinámica directamente especificada.

En el pasado, el vinculador consideraba que los símbolos en dependencias de idiomas específicos estaban disponibles. Pero eso cambió en alguna versión posterior y ahora el vinculador impone una visión más estricta de lo que está disponible. Por lo tanto, el mensaje está destinado a ayudar con esa transición.

¿Qué hacer?

Si eres el mantenedor del software

Debe resolver este problema asegurándose de que todas las bibliotecas necesarias para satisfacer los símbolos necesarios se especifiquen directamente en la línea de comando del vinculador. También tenga en cuenta que el orden a menudo es importante.

Si solo está intentando compilar el software

Como solución alternativa, es posible volver a la vista más permisiva de los símbolos disponibles mediante el uso de la opción -Wl,--copy-dt-needed-entries.

Las formas comunes de inyectar esto en una compilación son exportar LDFLAGS antes de ejecutarlo configureo similar de esta manera:

export LDFLAGS="-Wl,--copy-dt-needed-entries"

A veces, pasar LDFLAGS="-Wl,--copy-dt-needed-entries"directamente a makepodría funcionar también.

shell de texto
fuente
gcc versión 7.4.0 (Ubuntu 7.4.0-1ubuntu1 ~ 18.04.1) no reconoció esta bandera.
UserX
1
No es una opción de gcc, por lo que te falta el -Wl,bit o tienes un vinculador que no admite estas opciones. ¿Qué enlazador estás usando? Esta respuesta asume el clásico enlazador binutils (ld.bfd). El binutils gold linker (ld.gold) documenta --copy-dt-needed-entriescomo "No compatible". Entonces, si tiene ese (o cualquier otro vinculador que no sea compatible con esta opción) como predeterminado, es posible que deba seguir la sección para mantenedores o cambiar al clásico ld para vincular. Creo que puedes usar -fuse-ld=ld.bfdpara eso.
texthell
14

Encontré otro caso y, por lo tanto, creo que todos ustedes están equivocados.

Esto es lo que tenía:

/usr/lib64/gcc/x86_64-suse-linux/4.8/../../../../x86_64-suse-linux/bin/ld: eggtrayicon.o: undefined reference to symbol 'XFlush'
/usr/lib64/libX11.so.6: error adding symbols: DSO missing from command line

El problema es que la línea de comando NO contenía -lX11, aunque libX11.so debería agregarse como una dependencia porque también había bibliotecas GTK y GNOME en los argumentos.

Entonces, la única explicación para mí es que este mensaje podría haber sido para ayudarlo , pero no lo hizo correctamente. Esto probablemente fue simple: la biblioteca que proporciona el símbolo no se agregó a la línea de comando.

Tenga en cuenta tres reglas importantes sobre la vinculación en POSIX:

  • Las bibliotecas dinámicas tienen dependencias definidas, por lo que solo las bibliotecas de la dependencia superior se deben suministrar en cualquier orden (aunque después de las bibliotecas estáticas)
  • Las bibliotecas estáticas solo tienen símbolos indefinidos: depende de usted conocer sus dependencias y proporcionarlas todas en la línea de comandos
  • El orden en las bibliotecas estáticas es siempre: el solicitante primero , el proveedor sigue . De lo contrario, recibirá un mensaje de símbolo indefinido, como cuando olvidó agregar la biblioteca a la línea de comando
  • Cuando especificas la biblioteca con -l<name>, nunca sabes si tomará lib<name>.soo no lib<name>.a. Se prefiere la biblioteca dinámica, si se encuentra, y las bibliotecas estáticas solo se pueden aplicar mediante la opción del compilador, eso es todo. Y si tiene algún problema como el anterior, depende de si tenía bibliotecas estáticas o dinámicas.
  • Bueno, a veces pueden faltar las dependencias en las bibliotecas dinámicas: D
Ethouris
fuente
No solo está destinado a ayudarlo, sino que el vinculador lo requiere para resolver los nombres en cuestión. El error es completamente válido. Si el compilador decidiera dejarlo pasar, solo obtendría un defecto para acceder a algo que no está allí en el tiempo de ejecución binario.
kevr
1
Para agregar, es posible que en diferentes plataformas, la fuente se compile de manera diferente; lo que está vinculado en un sistema puede no estarlo en otro. Este no suele ser el caso, pero es 100% plausible.
kevr
El problema no es que no sea válido, sino que no sea exactamente útil encontrar la causa del problema.
Ethouris
7

Descubrí que tenía el mismo error. Estaba compilando un código tanto con lapack como con blas. Cuando cambié el orden en que se llamaban las dos bibliotecas, el error desapareció.

"LAPACK_LIB = -llapack -lblas" funcionó donde "LAPACK_LIB = -lblas -llapack" dio el error descrito anteriormente.

usuario3112632
fuente
9
Recibo este error en un proyecto definido por cmake ... entonces, ¿hay un error en Cmake que pone el orden del enlazador incorrecto?
Peter Karasev
respondiendo a @peterkarasev: intenta usar find_package(Threads)ytarget_link_libraries( ... ${CMAKE_THREAD_LIBS_INIT})
activedecay
7

También encontré el mismo problema. No sé por qué, solo agrego la -lpthreadopción al compilador y todo está bien.

Antiguo:

$ g++ -rdynamic -m64 -fPIE -pie  -o /tmp/node/out/Release/mksnapshot ...*.o *.a -ldl -lrt

Tengo el siguiente error. Si agrego la -lpthreadopción al comando anterior, entonces OK.

/usr/bin/ld: /tmp/node/out/Release/obj.host/v8_libbase/deps/v8/src/base/platform/condition-variable.o: undefined reference to symbol 'pthread_condattr_setclock@@GLIBC_2.3.3'
//lib/x86_64-linux-gnu/libpthread.so.0: error adding symbols: DSO missing from command line
collect2: error: ld returned 1 exit status
osexp2003
fuente
Esto funcionó para mí; Tuve que agregar un segundo subproceso "redundante" al comando g ++ en el archivo MAKE que hace el enlace. (Ya apareció una vez en la lista LIBS en el archivo MAKE). También agregué "-L / lib / x86_64-linux-gnu" a la definición de LDFLAGS en el archivo MAKE.
UserX
2

Lo que he encontrado es que a veces la biblioteca de la que se queja el vinculador no es la que causa el problema. Posiblemente hay una manera inteligente de averiguar dónde está el problema, pero esto es lo que hago:

  • Comente todas las bibliotecas vinculadas en el comando de enlace.
  • Limpie todos los .o, .so's, etc. (Por lo general, hacer la limpieza es suficiente, pero es posible que desee ejecutar un find recursivo + rm, o algo similar).
  • Descomente las bibliotecas en el comando de enlace de una en una y reorganice el orden según sea necesario.

@peter karasev: me he encontrado con el mismo problema con un proyecto gcc 4.8.2 cmake en CentOS7. El orden de las bibliotecas en la sección "target_link_libraries" es importante. Supongo que cmake simplemente pasa la lista al enlazador tal como está, es decir, no intenta resolver el orden correcto. Esto es razonable: cuando lo piensa, cmake no puede saber cuál es el orden correcto hasta que la vinculación se complete con éxito.

AhrB
fuente
2

Por favor agregue: CFLAGS="-lrt"yLDFLAGS="-lrt"

劉 大為
fuente
1

El mismo problema me sucedió cuando uso distccpara hacer mi proyecto de c ++; Finalmente lo resolví con export CXX="distcc g++".

Jason Geng
fuente
1

si está usando cmake y pthreads, intente agregar las siguientes líneas

find_package(Threads)
target_link_libraries(${CMAKE_THREAD_LIBS_INIT})
arquero han
fuente
0

Me sucedió lo mismo cuando estaba instalando el benchmark HPCC (incluye HPL y algunos otros benchmarks). Agregué -lma los indicadores del compilador en mi script de compilación y luego se compiló con éxito.

Jon Doh
fuente
3
Esto no responde a esta pregunta específica ni da una respuesta general para una familia de problemas similares. Esta es una respuesta altamente localizada para otra pregunta completamente .
Hermann Döppes
0

Si lo usa g++, asegúrese de no estar ejecutando en su gcclugar

Martin R.
fuente
3
¿Por qué? Podrías elaborar un poco?
Ivan Ivković
@ IvanIvković bueno, gcc es el compilador de C, g ++ es el compilador de C ++. Mientras que C ++ puede compilar C, gcc no puede compilar C ++.
Jean-Marc Zimmer
0

Intente agregar -pthreadal final de la lista de bibliotecas en el Makefile .

Funcionó para mi.

Ricky
fuente
0

Si está utilizando CMake, hay algunas formas en que podría resolverlo:

Solución 1: la más elegante

add_executable(...)
target_include_directories(...)
target_link_libraries(target_name pthread)

Solución 2: usando CMakefind_package

find_package(Threads REQUIRED) # this will generate the flag for CMAKE_THREAD_LIBS_INIT

add_executable(...)
target_include_directories(...)
target_link_libraries(target_name ${CMAKE_THREAD_LIBS_INIT})

Solución 3: cambiar las banderas CMake

# e.g. with C++ 17, change to other version if you need
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17 -pthread")
biendltb
fuente