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

16

274

When I'm compiling openvswitch-1.5.0, I've encountered the following compile error:

 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

If I try to see the symbols of libpthread, it looks fine.

$ 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

Could you give any hints or pointers?

Mccarthyism answered 11/11, 2013 at 8:33 Comment(4)
Also see Strange linking error: DSO missing from command line, DSO missing from command line, and Linking error: DSO missing from command line.Trihedron
link_libraries(pthread)Aruspex
# readelf -s /lib/x86_64-linux-gnu/libncurses.so readelf: Error: Could not locate '/lib/x86_64-linux-gnu/libncurses.so'. System error message: Too many levels of symbolic linksOaken
Possible duplicate of DSO missing from command lineEdytheee
E
212

You should mention the library on the command line after the object files being compiled:

 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 

Explanation: the linking is dependent on the order of modules. Symbols are first requested, and then linked in from a library that has them. So you have to specify modules that use libraries first, and libraries after them. Like this:

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

Moreover, in case there's a circular dependency, you should specify the same library on the command line several times. So in case libb needs symbol from libc and libc needs symbol from libb, the command line should be:

gcc x.o y.o z.o -la -lb -lc -lb
Englishism answered 11/11, 2013 at 11:53 Comment(2)
I think you can do -Wl,--start-group -la -lb- -lc -Wl,--end-group for circular dependencies.Viera
Note this also applies to source files--they should be listed before libraries. You can think of the resulting object files taking the place of the source files in the command line, and apply the same order as above.Gaillardia
C
90

Background

The DSO missing from command line message will be displayed when the linker does not find the required symbol with it's normal search but the symbol is available in one of the dependencies of a directly specified dynamic library.

In the past the linker considered symbols in dependencies of specified languages to be available. But that changed in some later version and now the linker enforces a more strict view of what is available. The message thus is intended to help with that transition.

What to do?

If you are the maintainer of the software

You should solve this problem by making sure that all libraries that are needed to satisfy the needed symbols are directly specified on the linker command line. Also keep in mind that order often matters.

If you are just trying to compile the software

As a workaround it's possible to switch back to the more permissive view of what symbols are available by using the option -Wl,--copy-dt-needed-entries. Put this option before the linked libraries, like g++ main.cc -Wl,--copy-dt-needed-entries -ltensorflow

Common ways to inject this into a build are to export LDFLAGS before running configure or similar like this:

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

Sometimes passing LDFLAGS="-Wl,--copy-dt-needed-entries" directly to make might also work.

Cletis answered 10/3, 2019 at 10:18 Comment(5)
gcc version 7.4.0 (Ubuntu 7.4.0-1ubuntu1~18.04.1) didn't recognize this flag.Slop
It's not a gcc option, so either you are missing the -Wl, bit, or you have an linker that does not support this options. What linker are you using? This answer assumes the classic binutils linker(ld.bfd). The binutils gold linker(ld.gold) documents --copy-dt-needed-entries as "Not supported". So if you have that (or any other linker that does not support this option) as default you might need to follow the section for maintainers or switch to the classic ld for linking. I think you can use -fuse-ld=ld.bfd for that.Cletis
This is the right answer if you are using g++ for C++ It describes the technical details and it gives the correct solution. The fact this answer does these things makes it the best. The fact that there are other issues in play causes this answer to be buried by "Use G++/Use GCC" answers that won't help if the seeker is using the right compiler.Sedative
worth noting that this has to be BEFORE the target library so e.g. g++ sound.o -o soundprogram -Wl,--copy-dt-needed-entries -lsfml-audioMichelle
To find the dependency you need, try scanelf. I got error undefined reference to symbol '_ZNK10...Ev' and diagnosed with scanelf -l -s _ZNK10...Ev | grep _ZNK10...Ev, which returned /usr/lib/libtensorflow.so, /usr/lib/libtensorflow_cc.so, and /usr/lib/libtensorflow_framework.so. I tried permutations of lib flags, and solved with -ltensorflow -ltensorflow_framework. See unix.stackexchange.com/questions/103744Dominga
S
60

The error message depends on distribution / compiler version:

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: (more informative)

/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

Solution: You may be missing a library in your compilation steps, during the linking stage. In my case, I added '-lz' to makefile / GCC flags.

Background: DSO is a dynamic shared object or a shared library.

Scullery answered 26/11, 2013 at 0:34 Comment(5)
I used this solution building another project that was giving the same error by adding -lz to the LDFLAGS and it worked perfectly. Thanks!Viaduct
The error still remain for me: /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 lineSherl
In part solved adding '-lpthread', but now it shows me: gaSim.c:(.text+0x11d6): undefined reference to `glewInit'Sherl
@Aerox: for glewInit, you need -lGLEWEphraim
thank you for spelling out the acronym.Magill
N
14

I found another case and therefore I thing you are all wrong.

This is what I had:

/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

The problem is that the command line DID NOT contain -lX11 - although the libX11.so should be added as a dependency because there were also GTK and GNOME libraries in the arguments.

So, the only explanation for me is that this message might have been intended to help you, but it didn't do it properly. This was probably simple: the library that provides the symbol was not added to the command line.

Please note three important rules concerning linkage in 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
Namecalling answered 14/7, 2016 at 13:34 Comment(3)
It is not only intended to help you, it is required by the linker to resolve the names in question. The error is completely valid. If the compiler decided to let that through, you would just get a segfault for accessing something that isn't there in the binary runtime.Reflux
To add, it is possible that on different platforms, the source is compiled differently; what is linked on one system may not be linked on another. This is usually not the case, but it is 100% plausible.Reflux
The problem isn't that it's not valid, but that it's not exactly helpful to find the cause of the problem.Namecalling
I
8

I also encountered same problem. I do not know why, i just add -lpthread option to compiler and everything ok.

Old:

$ g++ -rdynamic -m64 -fPIE -pie  -o /tmp/node/out/Release/mksnapshot ...*.o *.a -ldl -lrt

got following error. If i append -lpthread option to above command then 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
Imprison answered 29/8, 2016 at 16:43 Comment(1)
This worked for me; I had to add a second, "redundant" -lpthread to the g++ command in the makefile that does the link. (It already appeared once in the LIBS list in the makefile.) I also added "-L /lib/x86_64-linux-gnu" to the LDFLAGS definition in the makefile.Slop
S
7

I found I had the same error. I was compiling a code with both lapack and blas. When I switched the order that the two libraries were called the error went away.

"LAPACK_LIB = -llapack -lblas" worked where "LAPACK_LIB = -lblas -llapack" gave the error described above.

Selfstarter answered 17/12, 2013 at 19:30 Comment(2)
I get this error in a cmake-defined project... so is there a bug in Cmake that puts the linker order wrong?Placenta
replying to @peterkarasev : try using find_package(Threads) and target_link_libraries( ... ${CMAKE_THREAD_LIBS_INIT})Alic
T
7

If you are using CMake, there are some ways that you could solve it:

Solution 1: The most elegant one

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

Solution 2: using 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})

Solution 3: Change CMake flags

# 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")
Transfer answered 21/4, 2020 at 15:2 Comment(0)
A
3

What I have found is that sometimes the library that the linker complains about is not the one causing the problem. Possibly there is a clever way to work out where the problem is but this is what I do:

  • Comment out all the linked libraries in the link command.
  • Clean out all .o's, .so's etc (Usually make clean is enough, but you may want to run a recursive find + rm, or something similar).
  • Uncomment the libraries in the link command one at a time and re-arrange the order as necessary.

@peter karasev: I have come across the same problem with a gcc 4.8.2 cmake project on CentOS7. The order of the libraries in "target_link_libraries" section is important. I guess cmake just passes the list on to the linker as-is, i.e. it doesn't try and work out the correct order. This is reasonable - when you think about it cmake can't know what the correct order is until the linking is successfully completed.

Astute answered 5/2, 2015 at 9:31 Comment(0)
S
2

Please add: CFLAGS="-lrt" and LDFLAGS="-lrt"

Susann answered 13/4, 2017 at 8:16 Comment(0)
V
2

When working with code that uses mathematical functions, you should also link them. In my Case when compiling I provided the following, which worked for me.

mpicc -o testname testname.c -lm
Voguish answered 12/6, 2021 at 13:17 Comment(0)
H
1

The same problem happened to me when I use distcc to make my c++ project; Finally I solved it with export CXX="distcc g++".

Homogeneity answered 9/2, 2018 at 4:24 Comment(0)
C
1

Try to add -pthread at the end of the library list in the Makefile.

It worked for me.

Campestral answered 21/11, 2019 at 8:57 Comment(0)
E
1

if you are using cmake and used pthreads, try add the following lines

find_package(Threads)
target_link_libraries(${CMAKE_THREAD_LIBS_INIT})
Eanore answered 1/2, 2020 at 14:56 Comment(0)
K
1

Compile with g++ instead. It has worked in my case switching from gcc to g++.

Keelson answered 2/7, 2021 at 15:34 Comment(0)
M
0

The same thing happened to me as I was installing the HPCC benchmark (includes HPL and a few other benchmarks). I added -lm to the compiler flags in my build script and then it successfully compiled.

Melanism answered 4/12, 2016 at 18:41 Comment(1)
This does neither answer this specific question nor give a general answer for a family of similar problems. This is a highly localized answer for another question entirely.Cheloid
S
0

If using g++, make sure that you are not running gcc instead

Sully answered 21/6, 2018 at 22:46 Comment(2)
Why? Could you elaborate a bit?Segal
@IvanIvković well, gcc is the C compiler, g++ is the C++ compiler. While C++ can compile C, gcc cannot compile C++.Muzzle

© 2022 - 2024 — McMap. All rights reserved.