Странная ошибка связывания: DSO отсутствует в командной строке

когда я компилирую openvswitch-1.5.0, я столкнулся со следующей ошибкой компиляции:

 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

Если я попытаюсь увидеть символы libpthread, это выглядит нормально.

$ 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

не могли бы вы дать какие-либо подсказки или указатели?

10 ответов


вы должны упомянуть библиотеку в командной строке после объектные файлы, скомпилированные:

 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 

объяснение: связывание зависит от порядка следования модулей. Символы сначала запрашиваются, а затем связываются из библиотеки, в которой они есть. Поэтому сначала необходимо указать модули, использующие библиотеки,а затем библиотеки. Вот так:

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

кроме того, если есть круговая зависимость, вы должны указать ту же библиотеку на командная строка несколько раз. Так в случае libb нужен символ libc и libc нужен символ libb командная строка должна быть:

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

сообщение об ошибке зависит от дистрибутива / версии компилятора:

Ubuntu Дерзкий:

/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: (более информативно)

/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

устранение: на этапе компоновки может отсутствовать библиотека в шагах компиляции. В моем случае я добавил' - lz ' к флагам makefile / GCC.

Справочная информация: DSO-это динамический общий объект или общая библиотека.


я нашел другой случай, и поэтому я думаю, что вы все ошибаетесь.

вот что у меня было:

/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

проблема в том, что командная строка не содержит -lX11 - хотя libX11.поэтому следует добавить как зависимость, потому что в аргументах также были библиотеки GTK и GNOME.

Итак, единственное объяснение для меня заключается в том, что это сообщение могло быть предназначено для помочь, но он не сделал этого должным образом. Это было, вероятно, простой: библиотека, предоставляющая символ, не была добавлена в командную строку.

обратите внимание на три важных правила, касающиеся связи в POSIX:

  • динамические библиотеки имеют определенные зависимости, поэтому только библиотеки из верхней зависимости должны быть предоставлены в любом порядке (хотя после статических библиотек)
  • статические библиотеки имеют только неопределенные символы - это зависит от вас, чтобы узнать их зависимости и предоставить все из них в команде линия
  • порядок static библиотеки всегда: истец впервые, провайдер следующее. В противном случае вы получите неопределенное символьное сообщение, как когда вы забыли добавить библиотеку в командную строку
  • при указании библиотеки с -l<name>, вы никогда не знаете, будет ли он принимать lib<name>.so или lib<name>.a. Динамическая библиотека предпочтительнее, если она найдена, а статические библиотеки могут применяться только с помощью опции компилятора - это все. И есть ли у вас какие-либо проблемы, как указано выше, это зависит от того, были ли у вас статические или динамические библиотеки
  • ну, иногда зависимости могут отсутствовать в динамических библиотеках: D

Я обнаружил, что у меня была такая же ошибка. Я компиляции кода с lapack и Блас. Когда я переключил порядок вызова двух библиотек, ошибка исчезла.

" LAPACK_LIB = -llapack-lblas " работал там, где "LAPACK_LIB = -lblas-llapack" дал ошибку, описанную выше.


Я также столкнулся с той же проблемой. Не знаю почему, просто добавляю -lpthread опция компилятора и все в порядке.

старый:

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

получил следующее сообщение об ошибке. Если я добавлю -lpthread опция для команды выше, затем 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

Я обнаружил, что иногда библиотека, на которую жалуется компоновщик, не является причиной проблемы. Возможно, есть умный способ выяснить, где проблема, но это то, что я делаю:

  • прокомментируйте все связанные библиотеки в команде link.
  • очистить все .o's,.так и т. д. (Обычно достаточно очистить, но вы можете запустить рекурсивный find + rm или что-то подобное).
  • раскомментируйте библиотеки по ссылке командуйте по одному и при необходимости меняйте порядок.

@peter karasev: я столкнулся с той же проблемой с проектом gcc 4.8.2 cmake на CentOS7. Порядок библиотек в разделе "target_link_libraries" важно. Я думаю, cmake просто передает список компоновщику как есть, т. е. он не пытается выработать правильный порядок. Это разумно - когда вы думаете об этом, cmake не может знать, что такое правильный порядок, пока соединение не будет успешно завершенный.


пожалуйста, добавьте: CFLAGS="-lrt" и LDFLAGS="-lrt"


то же самое произошло со мной, когда я устанавливал тест HPCC (включает HPL и несколько других тестов). Я добавил -lm к флагам компилятора в моем скрипте сборки, а затем он успешно скомпилирован.


та же проблема произошла со мной, когда я использую distcc сделать мой проект c++ ; Наконец, я решил это с export CXX="distcc g++".


при использовании g++ убедитесь, что вы не используете