当我编译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
你能给我一些提示或指点吗?
我发现了另一个案子,所以我认为你们都错了。
这是我所拥有的:
/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. exe文件。所以应该作为依赖项添加,因为在参数中还有GTK和GNOME库。
所以,对我来说,唯一的解释是,这条信息可能是为了帮助你,但它没有正确地做到这一点。这可能很简单:提供该符号的库没有添加到命令行。
请注意POSIX中有关链接的三个重要规则:
Dynamic libraries have defined dependencies, so only libraries from the top-dependency should be supplied in whatever order (although after the static libraries)
Static libraries have just undefined symbols - it's up to you to know their dependencies and supply all of them in the command line
The order in static libraries is always: requester first, provider follows. Otherwise you'll get undefined symbol message, just like when you forgot to add the library to the command line
When you specify the library with -l<name>, you never know whether it will take lib<name>.so or lib<name>.a. The dynamic library is preferred, if found, and static libraries only can be enforced by compiler option - that's all. And whether you have any problems as above, it depends on whether you had static or dynamic libraries
Well, sometimes the dependencies may be lacking in dynamic libraries :D
如果你正在使用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")