libpthread.so.0:添加符号时出错:命令行缺少DSO


205

编译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

您能提供任何提示或指示吗?



link_libraries(pthread)
亚历克斯·普

#readelf -s /lib/x86_64-linux-gnu/libncurses.so readelf:错误:无法找到“ /lib/x86_64-linux-gnu/libncurses.so”。系统错误消息:太多级别的符号链接
Ashish Karpe


4
该死的,我也gcc没有g++
邮政自

Answers:


162

在编译目标文件,您应该在命令行上提及该库:

 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

23
我认为您可以-Wl,--start-group -la -lb- -lc -Wl,--end-group为循环依赖做。
Z玻色子2014年

2
请注意,这也适用于源文件-它们应在库之前列出。您可以在命令行中考虑生成的目标文件代替源文件,并应用与上述相同的顺序。
jspencer

使用make生成应用程序时,应该在哪里添加-lpthread?
codezombie

50

错误消息取决于发行版/编译器版本:

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

解决方案:在链接阶段,您可能在编译步骤中缺少库。就我而言,我在makefile / GCC标志中添加了“ -lz”。

背景: DSO是动态共享对象或共享库。


1
我使用此解决方案构建了另一个项目,该项目通过在LDFLAGS中添加-lz来给出相同的错误,并且效果很好。谢谢!
Mark Ellul 2014年

对于我来说,错误仍然存​​在:/ usr / bin / ld:gaSim.o:对符号'pthread_create @@ GLIBC_2.1'的未定义引用/lib/i386-linux-gnu/libpthread.so.0:添加符号时出错:DSO命令行中缺少
Aerox

在某种程度上解决了添加'-lpthread'的问题,但现在它向我展示:gaSim.c :(。text + 0x11d6):对`glewInit'的未定义引用
Aerox

@Aerox:因为glewInit,您需要-lGLEW
mchiasson

19

背景

DSO missing from command line当链接器无法通过常规搜索找到所需的符号,但该符号在直接指定的动态库的依赖项之一中可用时,将显示该消息。

过去,链接器认为在指定语言的依存关系中的符号可用。但这在某些更高版本中有所更改,现在链接器对可用内容进行了更严格的描述。因此,该消息旨在帮助实现该过渡。

该怎么办?

如果您是软件的维护者

您应通过确保在链接器命令行上直接指定满足所需符号所需的所有库来解决此问题。还请记住,顺序通常很重要。

如果您只是尝试编译软件

作为解决方法,可以使用option切换回更宽泛的可用符号视图-Wl,--copy-dt-needed-entries

将其注入到构建中的常见方法是在运行configure或类似的操作之前导出LDFLAGS :

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

有时LDFLAGS="-Wl,--copy-dt-needed-entries"直接传递给make也可能有效。


gcc版本7.4.0(Ubuntu 7.4.0-1ubuntu1〜18.04.1)无法识别此标志。
UserX

1
它不是gcc选项,因此您可能缺少该-Wl,位,或者您的链接器不支持此选项。您正在使用什么链接器?该答案假定使用经典的binutils链接器(ld.bfd)。binutils gold链接器(ld.gold)文档显示--copy-dt-needed-entries为“不支持”。因此,如果您具有该默认值(或任何其他不支持此选项的链接器)作为默认值,则可能需要遵循维护者的介绍,或切换至经典ld进行链接。我认为您可以使用-fuse-ld=ld.bfd
textshell

14

我发现了另一起案件,因此我觉得你们都错了。

这就是我所拥有的:

/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

它不仅旨在为您提供帮助,而且链接程序需要它来解析有问题的名称。该错误是完全有效的。如果编译器决定让它通过,那么您将得到一个段错误,用于访问二进制运行时中不存在的内容。
kevr

1
另外,在不同平台上,源代码的编译方式可能有所不同。在一个系统上链接的内容可能不会在另一个系统上链接。通常情况并非如此,但这是100%合理的。
kevr

问题不在于它不是无效的,而是找到问题的原因并没有完全的帮助。
Ethouris

7

我发现我有同样的错误。我正在用lapack和blas编译代码。当我切换两个库的调用顺序时,错误消失了。

当“ LAPACK_LIB = -lblas -llapack”给出上述错误时,“ LAPACK_LIB = -llapack -lblas”起作用。


9
我在cmake定义的项目中遇到此错误...因此Cmake中是否存在一个错误,使链接器顺序错误?
彼得·卡拉索夫2015年

回复@peterkarasev:尝试使用find_package(Threads)target_link_libraries( ... ${CMAKE_THREAD_LIBS_INIT})
activedecay

7

我也遇到了同样的问题。我不知道为什么,我只是添加-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

这对我有用;我必须在执行链接的makefile中的g ++命令中添加第二个“冗余” -lpthread。(它已经出现在makefile的LIBS列表中。)我还向makefile的LDFLAGS定义中添加了“ -L / lib / x86_64-linux-gnu”。
UserX

2

我发现,有时链接程序抱怨的库不是导致问题的库。可能有一种聪明的方法可以解决问题所在,但这就是我要做的:

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

@peter karasev:我在CentOS7上的gcc 4.8.2 cmake项目遇到了相同的问题。“ target_link_libraries”部分中的库顺序很重要。我猜cmake只是将列表按原样传递给链接器,即它不会尝试找出正确的顺序。这是合理的-当您考虑它时,cmake在成功完成链接之前不会知道正确的顺序。




1

如果您使用的是cmake和使用的pthread,请尝试添加以下几行

find_package(Threads)
target_link_libraries(${CMAKE_THREAD_LIBS_INIT})

0

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


3
这既不能回答这个特定的问题,也不能对一系列类似的问题给出一般性的答案。这完全另一个问题的高度本地化的答案。
HermannDöppes,2013年


0

尝试-pthreadMakefile中的库列表末尾添加。

它为我工作。


0

如果您使用的是CMake,可以通过以下几种方法解决它:

解决方案1:最优雅的一种

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

解决方案2:使用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})

解决方案3:更改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")
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.