奇怪的链接错误:命令行中缺少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 

你可以提供任何提示或指针?

在编译目标文件之后 ,应该在命令行上提到库:

  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 xo yo zo -la -lb -lc 

而且,如果存在循环依赖,则应多次在命令行上指定相同的库。 所以如果libb需要libc符号,而libc需要libb符号,命令行应该是:

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

谷歌带领我在这里..所以对于其他类似的问题

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:我收到了更多信息的错误消息

 /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 

问题是命令行DID不包含-lX11 – 虽然libX11.so应该作为依赖项添加,因为在参数中也有GTK和GNOME库。

所以,对我来说唯一的解释是这个消息可能是为了帮助你 ,但是没有做好。 这可能很简单:提供符号的库不会添加到命令行中。

请注意有关POSIX链接的三个重要规则:

  • 动态库已经定义了依赖关系,所以只有顶级依赖的库应该以任何顺序提供(尽管在静态库之后)
  • 静态库只有未定义的符号 – 取决于你自己的依赖关系,并在命令行中提供它们
  • 静态库中的顺序总是: 先请求者 ,然后是提供者 。 否则,您会收到未定义的符号消息,就像您忘记将库添加到命令行一样
  • 当您使用-l<name>指定库时,您永远不知道是否会使用lib<name>.solib<name>.a 。 动态库是最好的,如果找到了,静态库只能通过编译器选项强制 – 这就是全部。 不管你有什么问题,这取决于你是否有静态或动态库
  • 那么,有时在动态库中可能会缺少依赖关系:D

我发现我有同样的错误。 我正在编译一个包含lapack和blas的代码。 当我改变这两个图书馆的命令时,错误消失了。

“LAPACK_LIB = -llapack -lblas”在“LAPACK_LIB = -lblas -llapack”给出上述错误的地方工作。

我发现的是有时连接器所抱怨的库不是引起问题的库。 可能有一个聪明的方法来解决问题的地方,但这是我所做的:

  • 在链接命令中注释掉所有链接的库。
  • 清理掉所有的.o's,.so等等(通常清理就足够了,但是你可能想运行一个递归的find + rm或类似的东西)。
  • 取消链接命令中的库的注释,并根据需要重新排列顺序。

@peter karasev:我在CentOS7上遇到过与gcc 4.8.2 cmake项目相同的问题。 “target_link_libraries”部分中的库的顺序非常重要。 我想cmake只是将链表按照原样传递给链接器,也就是说,它不会尝试正确的顺序。 这是合理的 – 当你想到它,cmake不能知道正确的顺序是什么,直到链接成功完成。

我也遇到了同样的问题。 我不知道为什么,我只是添加-lpthread选项编译器,一切正常。

旧:

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

有以下错误。 如果我将-lpthread选项添加到上面的命令然后确定。

 /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 

请添加: CFLAGS="-lrt"LDFLAGS="-lrt"

同样的事情发生在我身上,因为我正在安装HPCC基准(包括HPL和其他一些基准测试)。 我在构建脚本中向编译器标志添加了-lm ,然后成功编译。

Interesting Posts