关于 linker 的问题,不确定是否是一个 bug

host 环境为 docker 下的 ubuntu 22.04,安装了 aarch64-linux-gnu-gcc(g++)-11。将远程 aarch64 的机器的 usr 和 lib 目录 rsync 到本机做 qt 交叉编译的 sysroot。 在编译到 3danimation 模块时报了一个问题:

/usr/lib/gcc-cross/aarch64-linux-gnu/11/../../../../aarch64-linux-gnu/bin/ld: /tmp/sysroot/usr/lib/aarch64-linux-gnu/libm.a(s_cbrt.o): in function `__cbrt':
(.text+0x34): undefined reference to `__frexp'
/usr/lib/gcc-cross/aarch64-linux-gnu/11/../../../../aarch64-linux-gnu/bin/ld: (.text+0x118): undefined reference to `__ldexp'
collect2: error: ld returned 1 exit status

之后我单独创建了一个 cpp 文件用来测试,发现如果不指定 -L/tmp/sysroot/usr/lib/aarch64-linux-gnu 是可以编译成功的,反之带上就不行了。同样的代码也在远程机器上做了测试,可以编译成功。

-lm

带上 -L$(sysroot) 后即使加了 -lm 也不管用

而且我看了下 __frexp 这个符号在 libc.a 里

看这个错误是使用了 /tmp/sysroot 目录下的 libm.a, 但是它又需要 /tmp/sysroot 下面的 libc.a, 现在似乎没有链接到 /tmp/sysroot 下的 libc.a 上。一般 libc.a 是在 /usr/lib/ 下面,所以你可能还得再 -L 一下 /tmp/sysroot/usr/lib. (建议使用 gcc --sysroot 选项来完成这个事情)

我的 sysroot 下的 libc.a 是在我链接的目录下的,而且也使用了 --sysroot 属性。两个测试都带了 --sysroot。

这是不成功的命令:

aarch64-linux-gnu-g++-11 main.cc --sysroot=/tmp/sysroot -L/tmp/sysroot/usr/lib/aarch64-linux-gnu -lm

这是成功的:

aarch64-linux-gnu-g++-11 main.cc --sysroot=/tmp/sysroot -lm

我知道为什么了,看起来 rsync 没有为软链接做正确工作,导致一些软链接的库实际路径不对,因此它没有找 libm.so, 而是找到了 libm.a

可能是我使用 rsync 的方式不正确,我只用了 -avz