很奇怪的链接器行为

Don*_*ool 45 linker gcc ld

这很奇怪,因为我能够通过删除对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
Run Code Online (Sandbox Code Playgroud)

所以,如果我删除-lm命令的一部分,我不会得到错误.但是,我想知道是否有人知道为什么删除对所需库的引用会解决这个问题.链接器如何知道要查找哪个库?另外 - 有没有办法查询已构建的可执行文件,并说'你在哪个库中解析了对'floor'的引用?显然,有些事情我不明白,这让我感到烦恼......

Emp*_*ian 84

对正在发生的事情的解释非常简单:

  1. libgplot.a要看libm.so,但顺序-lm-lgplot链接线是错误的.图书馆的链接线的顺序 事情.在一般情况下,系统库(-lpthread,-lm,-lrt, -ldl)应遵循链接线一切.

  2. 当您-lm从链接行中删除时,libm.so.6仍会被稍后出现在链接行(libgd,libxml2libcurl)上的其他库拉入链接,因为该库依赖于该链接libm.so.6.但现在libm.so.6在链接线上的位置正确,所以一切正常.

如果我把-lm放在link命令的末尾,将它列为最后一个库,我就不会收到错误.

这证实了上述解释.


dmn*_*mnc 8

我已经解决了同样的问题 export LDFLAGS="$LDFLAGS -lm"

  • `-lm` 用于链接标准 C 数学库 (2认同)

per*_*eal 6

也许,您的库搜索路径(/ usr/local/lib /或/ usr/lib /,...)不包含64位libm,因此如果您使用lflag 指定gcc,则无法找到它.如果您只指定它看起来可以找到正确的目录.所以你可以尝试:

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

并使用 -lm


Max*_*kin 3

很难说。因为命令行中有自定义库目录,所以可以想象-lm链接到不兼容的替代版本。如果没有-lm链接器,则可能会引入它的另一个版本,因为您链接的库之一需要它。

确保strace两种情况下的调用libm.so都来自何处。

顺便说一句,-Wlswitch 似乎什么也没做,并且-L/usr/lib/x86_64-linux-gnu被提到了两次。