我正在尝试使用 LLD 作为带有 gnu stdlib 实现的链接器,使用 LLVM 为 Raspberry Pi 进行交叉编译。我收到大量以下警告,这些警告涉及只读部分内的重定位,所有这些都包含在标准库实现中(似乎发生在 c 和 cpp 中)。
ld.lld: error: can't create dynamic relocation R_ARM_ABS32 against local symbol in readonly segment; recompile object files with -fPIC or pass '-Wl,-z,notext' to allow text relocations in the output
>>> defined in /home/ted/cross.llvm.raspbian/sysroot/usr/lib/gcc/arm-linux-gnueabihf/6.3.0/../../../arm-linux-gnueabihf/libm.a(s_atan.o)
>>> referenced by s_atan.o:(atanMp.constprop.0) in archive /home/ted/cross.llvm.raspbian/sysroot/usr/lib/gcc/arm-linux-gnueabihf/6.3.0/../../../arm-linux-gnueabihf/libm.a
虽然诊断告诉我使用 -z,notext
这是 apparently bad .有没有其他方法可以解决这个问题,或者我是否使用了不正确的交叉编译标志?
旁注:对于我使用的交叉编译
clang++ --target=arm-linux-gnueabihf --sysroot=./sysroot -fuse-ld=lld --verbose test.cpp -o test
./sysroot
包含来自 Raspberry 的 /usr
和 /lib
。
最佳答案
问题是默认情况下 clang 编译器会尝试链接动态库。您的动态库(很可能)是一个绝对路径的符号链接(symbolic link)。
对我来说是这样的:
$ ls -l /Volumes/AlphaRacing/emlid-rootfs/lib/arm-linux-gnueabihf/libm*
# ...
/Volumes/AlphaRacing/emlid-rootfs/lib/arm-linux-gnueabihf/libm.so -> /lib/arm-linux-gnueabihf/libm.so.6
只要你交叉编译,你的symlink源码的真实路径是不一样的。
所以你有两个选择:
- 使用
-static
标志编译。 - 修复这些符号链接(symbolic link)以使用相对路径。但请注意,它们有很多。
感谢this post ,它帮助我解决了这个问题。
关于LLVM 交叉编译无法创建动态重定位 R_ARM_ABS32,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55942607/