libpthread.so.0: error al agregar símbolos: falta DSO en la línea de comando
Cuando estoy compilando openvswitch-1.5.0, encontré 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 intento 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 darnos alguna pista o sugerencia?
Debe mencionar la biblioteca en la línea de comando después de compilar 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: la vinculación depende del orden de los módulos. Primero se solicitan los símbolos y luego se vinculan desde una biblioteca que los tenga. Por lo tanto, debe especificar módulos que usen bibliotecas primero y bibliotecas después. Como esto:
gcc x.o y.o z.o -la -lb -lc
Además, en caso de que exista una dependencia circular, debes 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 debe ser:
gcc x.o y.o z.o -la -lb -lc -lb
Fondo
El 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 especificada directamente.
En el pasado, el enlazador 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 tanto, el mensaje pretende ayudar en 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 muchas veces es importante.
Si solo estás intentando compilar el software
Como solución alternativa, es posible volver a la vista más permisiva de qué símbolos están disponibles usando la opción -Wl,--copy-dt-needed-entries
. Coloque esta opción antes de las bibliotecas vinculadas, comog++ main.cc -Wl,--copy-dt-needed-entries -ltensorflow
Las formas comunes de inyectar esto en una compilación son exportar LDFLAGS antes de ejecutar configure
o similar como este:
export LDFLAGS="-Wl,--copy-dt-needed-entries"
A veces, pasar LDFLAGS="-Wl,--copy-dt-needed-entries"
directamente a make
también podría funcionar.