libpthread.so。0:添加符号错误:命令行中缺少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

你能给我一些提示或指点吗?

586758 次浏览

你应该在命令行中提到正在编译的目标文件的库:

 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

你可能会在你的编译步骤中丢失一个库,在链接阶段。在我的例子中,我在makefile / GCC标志中添加了'-lz'。

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

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

"LAPACK_LIB = - lapack -lblas"工作在哪里 "LAPACK_LIB = -lblas - lapack"给出了上面描述的错误

我发现有时候链接程序抱怨的库并不是引起问题的那个库。也许有一个聪明的方法来解决问题,但这就是我所做的:

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

@peter karasev:我在CentOS7上的gcc 4.8.2 cmake项目中遇到了同样的问题。“target_link_libraries”部分中的库的顺序很重要。我猜cmake只是将列表原样传递给链接器,也就是说,它不会尝试并计算出正确的顺序。这是合理的——当你思考它时,cmake不知道正确的顺序是什么,直到链接成功完成。

我发现了另一个案子,所以我认为你们都错了。

这是我所拥有的:

/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. xml文件没有包含-lX11。所以应该作为依赖项添加,因为在参数中还有GTK和GNOME库。

所以,对我来说唯一的解释是,这个消息可能已经打算帮助你,但它没有正确地这样做。这可能很简单:提供该符号的库没有添加到命令行。

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

  • 动态库已经定义了依赖关系,因此只能按任意顺序提供顶层依赖关系的库(尽管在静态库之后)
  • 静态库只有未定义的符号——这取决于你是否知道它们的依赖关系,并在命令行中提供所有这些符号
  • 静态库中的顺序始终是:请求者的第一个供应商之前。否则,您将得到未定义的符号消息,就像您忘记将库添加到命令行一样
  • 当你用-l<name>指定标准库时,你永远不知道它会取lib<name>.so还是lib<name>.a。如果找到动态库,则首选动态库,而静态库只能通过编译器选项强制执行——仅此而已。无论您是否遇到上述问题,这取决于您使用的是静态库还是动态库
  • 嗯,有时候动态库中可能缺乏依赖关系:D

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

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

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

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

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

背景

当链接器在正常搜索中没有找到所需的符号,但该符号在直接指定的动态库的依赖项之一中可用时,将显示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也可以工作。

尝试将-pthread添加到Makefile. xml中库列表的末尾。

这对我很管用。

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

find_package(Threads)
target_link_libraries(${CMAKE_THREAD_LIBS_INIT})

如果你正在使用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")
在处理使用数学函数的代码时,还应该链接它们。 在我的情况下,当编译时,我提供了以下,这对我有用
mpicc -o testname testname.c -lm

改用g++编译。在我的案例中,从gcc切换到g++是有效的。