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

libpthread.so.0: error adding symbols: DSO missing from command line

提问人:jaeyong 提问时间:11/11/2013 最后编辑:jwwjaeyong 更新时间:6/28/2023 访问量:641332

问:

当我编译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 编译器错误 链接器 未定义引用

评论

2赞 jww 1/10/2017
另请参阅奇怪的链接错误:命令行中缺少 DSO、命令行中缺少 DSO链接错误:命令行中缺少 DSO
0赞 Alex Punnen 5/10/2017
link_libraries(pthread)
0赞 Ashish Karpe 10/17/2017
# readelf -s /lib/x86_64-linux-gnu/libncurses.so readelf:错误:找不到 '/lib/x86_64-linux-gnu/libncurses.so'。系统错误消息:符号链接级别过多
0赞 luator 12/12/2017
命令行中可能缺少 DSO 的重复项

答:

208赞 Michael Pankov 11/11/2013 #1

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

 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

此外,如果存在循环依赖关系,则应在命令行上多次指定相同的库。因此,如果 needs symbol from 和 needs symbol from ,命令行应该是:libblibclibclibb

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

评论

31赞 Z boson 10/28/2014
我认为你可以为循环依赖做。-Wl,--start-group -la -lb- -lc -Wl,--end-group
2赞 jspencer 1/11/2015
请注意,这也适用于源文件,它们应列在库之前。您可以考虑在命令行中将生成的对象文件代替源文件,并应用与上述相同的顺序。
60赞 Kevin 11/26/2013 #2

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

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赞 Mark Ellul 4/14/2014
我使用此解决方案构建了另一个项目,该项目通过将 -lz 添加到 LDFLAGS 来产生相同的错误,并且它运行良好。谢谢!
0赞 Aerox 6/26/2014
我仍然保留错误: /usr/bin/ld: gaSim.o: undefined reference to symbol 'pthread_create@@GLIBC_2.1' /lib/i386-linux-gnu/libpthread.so.0: error adding symbols: DSO missing from command line
0赞 Aerox 6/26/2014
部分解决了添加“-lpthread”的问题,但现在它向我显示:gaSim.c:(.text+0x11d6):对“glewInit”的未定义引用
1赞 mchiasson 8/3/2016
@Aerox:对于,您需要glewInit-lGLEW
0赞 Alex 10/27/2022
感谢您拼出首字母缩略词。
7赞 user3112632 12/18/2013 #3

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

“LAPACK_LIB = -llapack -lblas”在哪里工作 “LAPACK_LIB = -lblas -llapack”给出了上述错误。

评论

10赞 peter karasev 1/21/2015
我在 cmake 定义的项目中收到此错误...那么 Cmake 中是否存在错误,导致链接器顺序错误?
0赞 activedecay 6/30/2018
回复 @peterkarasev : Try using 和find_package(Threads)target_link_libraries( ... ${CMAKE_THREAD_LIBS_INIT})
3赞 AhrB 2/5/2015 #4

我发现,有时链接器抱怨的库并不是导致问题的库。可能有一种聪明的方法可以找出问题所在,但这就是我所做的:

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

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

14赞 Ethouris 7/14/2016 #5

我发现了另一个案例,因此我认为你们都错了。

这是我所拥有的:

/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

问题是命令行不包含 - 尽管应该将 libX11.so 添加为依赖项,因为参数中还有 GTK 和 GNOME 库。-lX11

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

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

  • 动态库定义了依赖关系,因此只能按任何顺序提供来自顶层依赖关系的库(尽管在静态库之后)
  • 静态库只有未定义的符号 - 由您了解它们的依赖关系并在命令行中提供所有符号
  • 静态库中的顺序始终是:请求者在前提供者在后。否则,您将收到未定义的符号消息,就像您忘记将库添加到命令行一样
  • 当您使用 指定库时,您永远不知道它是否会采用 或 。如果找到动态库,则首选,并且静态库只能通过编译器选项强制执行 - 仅此而已。无论您是否有上述问题,这取决于您是有静态库还是动态库-l<name>lib<name>.solib<name>.a
  • 好吧,有时动态库中可能缺少依赖项:D

评论

0赞 kevr 1/25/2018
它不仅旨在帮助您,链接器还需要它来解析有问题的名称。该错误是完全有效的。如果编译器决定让它通过,你只会因为访问二进制运行时中不存在的东西而得到一个段错误。
1赞 kevr 1/25/2018
此外,在不同的平台上,源代码的编译方式可能不同;在一个系统上链接的内容可能不会在另一个系统上链接。通常情况并非如此,但这是 100% 合理的。
0赞 Ethouris 1/9/2019
问题不在于它无效,而在于它对找到问题的原因没有帮助。
8赞 osexp2000 8/30/2016 #6

我也遇到了同样的问题。我不知道为什么,我只是向编译器添加选项,一切正常。-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

评论

0赞 UserX 9/13/2019
这对我有用;我不得不在执行链接的 makefile 中的 g++ 命令中添加第二个“冗余”-lpthread。(它已经在 makefile 的 LIBS 列表中出现过一次。我还将“-L /lib/x86_64-linux-gnu”添加到makefile的LDFLAGS定义中。
0赞 Jon Doh 12/5/2016 #7

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

评论

3赞 Hermann Döppes 12/5/2016
这既不能回答这个具体问题,也不能为一系列类似问题给出一般答案。对于另一个问题来说,这是一个高度本地化的答案。
2赞 劉大為 4/13/2017 #8

请补充: 以及CFLAGS="-lrt"LDFLAGS="-lrt"

1赞 Jason Geng 2/9/2018 #9

当我用来制作我的 c++ 项目时,同样的问题也发生在我身上; 最后我用 解决了它。distccexport CXX="distcc g++"

0赞 Martin R. 6/22/2018 #10

如果使用 ,请确保您不是在运行g++gcc

评论

3赞 Glorious Kale 3/14/2019
为什么?你能详细说明一下吗?
1赞 Jean-Marc Zimmer 7/1/2020
@IvanIvković,gcc 是 C 编译器,g++ 是C++编译器。虽然 C++ 可以编译 C,但 gcc 不能编译 C++。
79赞 textshell 3/10/2019 #11

背景

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

过去,链接器认为指定语言的依赖项中的符号可用。但是在后来的版本中,情况发生了变化,现在链接器对可用内容强制执行更严格的视图。因此,该信息旨在帮助实现这一转变。

该怎么办?

如果您是软件的维护者

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

如果您只是想编译软件

作为一种解决方法,可以使用选项切换回更宽松的视图,了解哪些符号可用。将此选项放在链接库之前,例如-Wl,--copy-dt-needed-entriesg++ main.cc -Wl,--copy-dt-needed-entries -ltensorflow

将其注入构建的常见方法是在运行之前导出 LDFLAGS,或类似如下:configure

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

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

评论

0赞 UserX 9/13/2019
gcc 版本 7.4.0 (Ubuntu 7.4.0-1ubuntu1~18.04.1) 无法识别此标志。
1赞 textshell 9/14/2019
它不是 gcc 选项,因此要么您缺少位,要么您的链接器不支持此选项。您使用的是什么链接器?此答案假定使用经典的 binutils 链接器 (ld.bfd)。binutils gold linker(ld.gold) 文档为“不支持”。因此,如果您默认使用它(或任何其他不支持此选项的链接器),您可能需要遵循维护者部分或切换到经典 ld 进行链接。我认为你可以用它来。-Wl,--copy-dt-needed-entries-fuse-ld=ld.bfd
0赞 cardiff space man 5/26/2022
如果您将 g++ 用于 C++,这是正确的答案 它描述了技术细节并给出了正确的解决方案。事实上,这个答案做了这些事情,使它成为最好的。事实上,还有其他问题在起作用,导致这个答案被“使用 G++/使用 GCC”的答案所掩盖,如果搜索者使用的是正确的编译器,这些答案将无济于事。
3赞 jave.web 11/3/2022
值得注意的是,这必须在目标库之前,例如g++ sound.o -o soundprogram -Wl,--copy-dt-needed-entries -lsfml-audio
0赞 Mark Peschel 6/25/2023
要查找所需的依赖项,请尝试 。我收到错误并被诊断为 ,它返回了 /usr/lib/libtensorflow.so、/usr/lib/libtensorflow_cc.so 和 /usr/lib/libtensorflow_framework.so。我尝试了 lib 标志的排列,并用 .查看 unix.stackexchange.com/questions/103744scanelfundefined reference to symbol '_ZNK10...Ev'scanelf -l -s _ZNK10...Ev | grep _ZNK10...Ev-ltensorflow -ltensorflow_framework
1赞 Ricky 11/21/2019 #12

尝试在 Makefile 中库列表的末尾添加。-pthread

它对我有用。

1赞 bowman han 2/1/2020 #13

如果您使用的是 CMake 并使用了 pthreads,请尝试添加以下行

find_package(Threads)
target_link_libraries(${CMAKE_THREAD_LIBS_INIT})
5赞 biendltb 4/21/2020 #14

如果您使用的是 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")
2赞 Niroshan Ratnayake 6/12/2021 #15

使用使用数学函数的代码时,还应链接它们。 就我而言,在编译时,我提供了以下内容,这对我有用。

mpicc -o testname testname.c -lm
1赞 alienflow 7/2/2021 #16

改用 g++ 进行编译。在我的情况下,它从 gcc 切换到 g++ 已经起作用了。