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

时间:2013-11-11 08:33:39

标签: gcc compiler-errors linker undefined-reference

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

你能给出任何提示或指示吗?

15 个答案:

答案 0 :(得分:131)

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

 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

答案 1 :(得分:45)

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

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是动态共享对象或共享库。

答案 2 :(得分: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>.so还是lib<name>.a。如果找到动态库,则首选动态库,并且只能通过编译器选项强制执行静态库 - 这就是全部。如果你有任何问题,这取决于你是否有静态或动态库
  • 好吧,有时动态库中可能缺少依赖关系:D

答案 3 :(得分:6)

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

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

答案 4 :(得分:4)

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

答案 5 :(得分:2)

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

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

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

答案 6 :(得分:2)

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

答案 7 :(得分:1)

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

答案 8 :(得分:1)

背景

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

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

该怎么办?

如果您是软件的维护者

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

如果您只是尝试编译软件

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

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

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

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

答案 9 :(得分:1)

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

find_package(Threads)
target_link_libraries(${CMAKE_THREAD_LIBS_INIT})

答案 10 :(得分:1)

处理使用数学函数的代码时,您还应该链接它们。 在我的案例中,我在编译时提供了以下内容,这对我有用。

mpicc -o testname testname.c -lm

答案 11 :(得分:0)

如果使用g++,请确保您没有运行gcc

答案 12 :(得分:0)

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

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

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

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

答案 13 :(得分:0)

改为使用 g++ 编译。在我从 gcc 切换到 g++ 的情况下,它起作用了。

答案 14 :(得分:-1)

尝试在{em> Makefile 的库列表末尾添加-pthread

对我有用。