Very strange linker behavior

This is strange because I was able to get the error below to get away by deleting the libm link.

gcc -o example example.o -Wl -L/home/kensey/cdev/lib -L/usr/lib/x86_64-linux-gnu -lmysqlclient -lpthread -lz -L/usr/lib/x86_64-linux-gnu -lm -lrt -ldl -lcdev -L/home/kensey/www.tools/gplot-lib -lgplot -L/home/kensey/www.tools/gd1_3ret -lgd -lxml2 -lcurl /usr/bin/ld: /home/kensey/www.tools/gplot-lib/libgplot.a(set.o): undefined reference to symbol 'floor@@GLIBC_2.2.5' /usr/bin/ld: note: 'floor@@GLIBC_2.2.5' is defined in DSO /usr/lib/x86_64-linux-gnu/libm.so so try adding it to the linker command line /usr/lib/x86_64-linux-gnu/libm.so: could not read symbols: Invalid operation collect2: ld returned 1 exit status 

So, if I remove the -lm part of the command, I will not get an error. However, I am wondering if anyone knows why removing the link to the desired library will fix this. How does the linker know which library to look for? Also, is there a way to request the embedded executable and say: β€œIn which library did you decide to link toβ€œ gender ”? Obviously, something is happening, I don’t understand, and it bothers me ...

+44
gcc linker ld
Mar 29 2018-12-12T00:
source share
8 answers

The explanation of what happens is very simple:

  • Your libgplot.a depends on libm.so , but the order of -lm and -lgplot on the link line is incorrect. The order of libraries in the link line is a question . In general, system libraries ( -lpthread , -lm , -lrt , -ldl ) should follow everything else in the link line.

  • When you remove -lm from the link line, libm.so.6 is still pulled into the link by another library, which appears later in the link line ( libgd , libxml2 or libcurl ) because this library depends on libm.so.6 . But now libm.so.6 is in the right place on the link, and so everything works.

if I put -lm at the end of the link, specifying it as the last library, I do not get an error.

This confirms the above explanation.

+82
Apr 23 '12 at 4:01
source share

I solved the same problem with export LDFLAGS="$LDFLAGS -lm"

+8
Apr 25 '13 at 10:28
source share

Perhaps your search paths in the library (/ usr / local / lib / or / usr / lib /, ...) do not contain 64-bit libm, so gcc cannot find it if you specify the l flag. If you specify only the directory on which it resembles, it can find the correct one. So you can try:

LD_LIBRARY_PATH=/usr/lib/x86_64-linux-gnu

and use -lm

+6
Mar 29 2018-12-12T00:
source share

Hard to say. Because there are custom library directories on the command line, it is possible that -lm binds an incompatible alternate version. Without -lm linker could pull out another version because it needs one of the libraries that you link.

To make sure strace both calls and see where libm.so occurs in both cases.

By the way, the -Wl switch does nothing, and the -L/usr/lib/x86_64-linux-gnu is mentioned twice.

+3
Mar 29 2018-12-12T00:
source share

Just add http://fedoraproject.org/wiki/UnderstandingDSOLinkChange to the answer list. This is informative. This does not apply to the question asked above, but the explanation refers to the error message /usr/bin/ld: note: 'some_reference' is defined in DSO some.so so try adding it to the linker command line

+2
May 20 '13 at 9:27
source share

One explanation could be:

Perhaps there is a loosely coupled function foo defined outside libm that is replaced by a tightly coupled version of foo defined inside libm, and it is this tightly coupled version that calls the undefined function.

This explains how adding a library can cause an undefined function error.

+1
Mar 29 2018-12-12T00:
source share

I ran into a similar problem; I remember that the order of the libraries did not matter (at least in the cases when I worked) in the past for gcc. In this question, someone noticed here that the behavior seems to have changed between 4.4 and 4.5.

In my case, I got rid of the error message by following the link:

  g++ -Wl,--copy-dt-needed-entries [options] [libraries] [object files] -o executable-file 
+1
Jun 03 '13 at 20:01
source share

Use this:

 administrator@administrator-Veriton-M200-H81:~/ishan$ gcc polyscanline1.cpp -lglut -lGLU -lGL -lm 
-one
Feb 25 '16 at 6:00
source share



All Articles