LLVM 交叉编译无法创建动态重定位 R_ARM_ABS32

标签 llvm cross-compiling libstdc++

我正在尝试使用 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源码的真实路径是不一样的。

所以你有两个选择:

  1. 使用 -static 标志编译。
  2. 修复这些符号链接(symbolic link)以使用相对路径。但请注意,它们有很多。

感谢this post ,它帮助我解决了这个问题。

关于LLVM 交叉编译无法创建动态重定位 R_ARM_ABS32,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55942607/

相关文章:

c++ - 从 std::istream 读取 LLVM IR

c - GCC 和 Clang 优化选项之间的区别

ios - 为什么 [@(!var) class] 返回'__NSCFNumber'而不是'__NSCFBoolean'?

c++ - 编译 qt 项目给 operator delete(void*, unsigned int) undefined reference

linux - 用于交叉编译的库(armel)

c++ - constexpr 上下文中的 std::optional 赋值运算符

llvm - 如何找到或生成示例 LLVM 项目?

c++ - 我的交叉编译器找不到共享库

C++11 随机数分布在不同平台之间不一致——有什么替代方案?

c++ - 将 std::to_wstring 与 libstdc++ 一起使用?