Very strange linker behavior
Solution 1
The explanation to what's happening is very simple:
Your
libgplot.a
depends onlibm.so
, yet the order of-lm
and-lgplot
on the link line is wrong. The order of libraries on the link line does matter. In general, system libraries (-lpthread
,-lm
,-lrt
,-ldl
) should follow everything else on the link line.When you remove
-lm
from the link line,libm.so.6
is still pulled into the link by some other library that appears later on the link line (libgd
,libxml2
orlibcurl
) because that library depends onlibm.so.6
. But nowlibm.so.6
is in correct place on the link line, and so everything works.
if I put -lm at the end of the link command, listing it as the last library, I do not get the error.
That confirms above explanation.
Solution 2
I've solved the same problem with export LDFLAGS="$LDFLAGS -lm"
Solution 3
Perhaps, your library search paths (/usr/local/lib/ or /usr/lib/, ...) do not contain 64bit libm so gcc cannot locate it if you specify with l
flag. If you only specify only the directory it looks like it can find the right one. So you can try:
LD_LIBRARY_PATH=/usr/lib/x86_64-linux-gnu
and use -lm
Solution 4
Hard to tell. Because there are custom library directories in the command line it's conceivable that -lm
links an incompatible alternative version. Without -lm
the linker could pull in another version of it because it's needed by one of the libraries you link.
To make sure strace
both invocations and see where libm.so
is coming from in both cases.
BTW, -Wl
switch seems to do nothing and -L/usr/lib/x86_64-linux-gnu
is mentioned twice.
Solution 5
Just to add to the list of answers, http://fedoraproject.org/wiki/UnderstandingDSOLinkChange It is informative. It isn't relevant to the question asked above, but, the explanation relates 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
Related videos on Youtube
Don Wool
Updated on July 09, 2022Comments
-
Don Wool almost 2 years
This is strange because I was able to get the error below to go away by removing the reference to libm.
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 do not get the error. However, I wonder if anyone knows as to why removing a reference to a library that is needed would fix this. How does the linker know which library to look in? Also - is there a way to query a built executable and say 'which library did you resolve the reference to 'floor'? obviously, there is something going on that I don't understand, and that bothers me...-
Andre Holzner about 11 yearsthe
-Wl
option is normally followed by a comma (to pass the text after the comma as an option to the linker), what do you intend to do with it ?
-
-
Maxim Egorushkin about 12 yearsNote, that the symbol is versioned. Does it still apply?
-
Andrew Tomazos about 12 years@MaximYegorushkin: Not sure sorry. I think the version of the undefined symbol is orthogonal to my possible diagnosis.
-
Don Wool about 12 yearsok I played around some more, and if I put -lm at the end of the link command, listing it as the last library, I do not get the error. The theory of a non 64bit libm might still be the case, as perhaps it can 'find the right one' before it gets to -lm at the end of the command, so the -lm is essentially ignored. fyi - I queried the libm via 'ar -t' and it listed the contents of the library ok. so that would imply its 64 bit/searchable.
-
Don Wool about 12 yearsopen("/lib/x86_64-linux-gnu/libm.so.6", O_RDONLY|O_CLOEXEC) = 3 read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0pU\0\0\0\0\0\0"..., 832) = 832 fstat(3, {st_mode=S_IFREG|0644, st_size=1022320, ...}) = 0
-
Don Wool about 12 yearsit turned out to be the same for both.. <br>kensey@kensey:~/cdev$ strace ./example 2>&1 | grep libm open("/usr/lib/x86_64-linux-gnu/libmysqlclient.so.18", O_RDONLY|O_CLOEXEC) = 3 open("/lib/x86_64-linux-gnu/libm.so.6", O_RDONLY|O_CLOEXEC) = 3 <br>so, I am not sure why this was a problem, but luckily it went away. I guess the lesson is : make sure libraries come after other libraries that may reference them. there is probably a way with strace to do more investigation, but I am new to that tool. thx for the help!
-
Andre Holzner about 11 yearsin fact, it seems to me this is a change of behaviour with respect to earlier versions of the GNU toolchain. If I remember correctly, was the order of the libraries given irrelevant in the past for gcc and it was smart enough to find the symbols. With xlC on AIX, the order was important if I remember correctly also in the past...
-
Jonathan Wakely about 11 yearsThe GCC version is irrelevant, you're talking about a linker change not a compiler one.
-
wukong almost 11 yearsThanks for this very detailed explanation
-
Qix - MONICA WAS MISTREATED over 9 yearsYep; explicitly adding
-lm
was the issue. Thank you! -
lesolorzanov almost 9 yearsCan you explain what this does?
-
dmnc over 8 years
-lm
for linking against the standard C math library -
Colin Keenan over 7 yearsMy problem wasn't exactly the original question, but adding -lm in the makefile at the end of my LDFLAGS definition worked. Thanks.