Extraño error de enlace: falta DSO en la línea de comandos

Cuando estoy comstackndo openvswitch-1.5.0, me he encontrado con el siguiente error de comstackció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 algunas pistas o consejos?

Debe mencionar la biblioteca en la línea de comando después de comstackr los archivos objeto:

  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: el enlace 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 primero usan bibliotecas y luego las bibliotecas. Me gusta esto:

 gcc xo yo zo -la -lb -lc 

Además, en caso de que exista una dependencia circular, debe especificar la misma biblioteca en la línea de comando varias veces. Entonces, en caso de que libb necesite el símbolo de libc y libc necesite el símbolo de libb , la línea de comando debería ser:

 gcc xo yo zo -la -lb -lc -lb 

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

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 comstackción, durante la etapa de enlace. En mi caso, agregué ‘-lz’ a makefile / banderas GCC.

Antecedentes: DSO es un objeto compartido dynamic o una biblioteca compartida.

Encontré otro caso y, por lo tanto, creo que estás equivocado.

Esto es lo que tuve:

 /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 el 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 tenido la intención de ayudarlo , pero no lo hizo correctamente. Esto fue probablemente 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 suministrarlas a todas en la línea de comando
  • El orden en las bibliotecas estáticas es siempre: solicitante primero , 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 especifica la biblioteca con -l , nunca se sabe si tomará lib.so o lib.a . La biblioteca dinámica es preferible, si se encuentra, y las bibliotecas estáticas solo pueden aplicarse mediante la opción del comstackdor, eso es todo. Y si tiene algún problema como el anterior, depende de si tiene bibliotecas estáticas o dinámicas
  • Bueno, a veces las dependencias pueden faltar en las bibliotecas dinámicas: D

Encontré que tenía el mismo error. Estaba comstackndo un código con ambos, lapack y blas. Cuando cambié el orden en que se llamaron las dos bibliotecas, el error desapareció.

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

También encontré el mismo problema. No sé por qué, solo -lpthread opción -lpthread al comstackdor y todo está bien.

Antiguo:

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

obtuve el siguiente error Si -lpthread opción -lpthread 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 

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

  • Comente todas las bibliotecas vinculadas en el comando de enlace.
  • Limpie todos los archivos .o, .so, etc. (Por lo general, limpiar es suficiente, pero es posible que desee ejecutar un hallazgo recursivo + rm, o algo similar).
  • Descomente las bibliotecas en el comando de enlace de a una por vez y vuelva a organizar el pedido según sea necesario.

@peter karasev: He encontrado el mismo problema con un proyecto gmac 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 piensas, cmake no puede saber cuál es el orden correcto hasta que el enlace se haya completado con éxito.

Por favor agregue: CFLAGS="-lrt" y LDFLAGS="-lrt"

Lo mismo me sucedió a mí cuando estaba instalando el punto de referencia HPCC (incluye HPL y algunos otros puntos de referencia). -lm a los indicadores del comstackdor en mi script de comstackción y luego compilé con éxito.

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

Si usa g++ , asegúrese de no estar ejecutando gcc