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

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

其他回答

请添加:CFLAGS=“-lrt” 和 LDFLAGS=“-lrt”

同样的问题发生在我使用distcc做我的c++项目; 最后我用export CXX="distcc g++"解决了它。

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

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

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

如果你正在使用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")

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

"LAPACK_LIB = - lapack -lblas"工作的地方 "LAPACK_LIB = -lblas - lapack"给出了上面描述的错误。