【问题标题】:How do you update the GNU linker for an Android NDK?如何更新 Android NDK 的 GNU 链接器?
【发布时间】:2017-10-23 18:36:48
【问题描述】:

我正在使用 NDK r12b 开发一个原生 Android 项目。这个 NDK(从那以后看起来和所有其他的)都附带一个预构建的 GNU 链接器版本 2.25。我们最近试图拉出我们项目的许多子模块,这些子模块引入了一个看起来像是由this bug in ld 引起的构建错误。

构建错误输出:

/opt/android-ndk-r12b/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/../lib/gcc/arm-linux-androideabi/4.9.x/../../../../arm-linux-androideabi/bin/ld: internal error in do_relocate_sections, at /usr/local/google/buildbot/src/android/gcc/toolchain/build/../binutils/binutils-2.25/gold/reloc.cc:953
collect2: error: ld returned 1 exit status

我以为我会尝试更新链接器,但没有找到预构建的二进制文件。所以我陷入了尝试自己编译 ld/binutils 的兔子洞。要么我的 Google 技能不及格,要么这样做的文档真的很少见,或者假设用户有很多我没有的介绍性知识。

使用 target=arm-linux 构建 binutils 2.29.1 时,我的应用程序构建错误并出现以下结果:

/opt/android-ndk-r12b/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/../lib/gcc/arm-linux-androideabi/4.9.x/../../../../arm-linux-androideabi/bin/ld: unrecognised emulation mode: armelf_linux_eabi
Supported emulations: armelf_linux armelf armelfb armelfb_linux
collect2: error: ld returned 1 exit status

作为参考,我们当前版本的 ld 的 -V 输出为:

me@linux-vm:/opt/android-ndk-r12b/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/arm-linux-androideabi/bin$ ./ld-2.25 -V
GNU gold (binutils-2.25-0666073 2.25.51.20141117) 1.11
Supported targets:
   elf64-littleaarch64
   elf64-bigaarch64
   elf32-littleaarch64
   elf32-bigaarch64
   elf64-tradlittlemips
   elf32-tradlittlemips-nacl
   elf64-tradbigmips
   elf32-tradlittlemips-nacl
   elf32-tradlittlemips
   elf32-tradlittlemips-nacl
   elf32-tradbigmips
   elf32-tradlittlemips-nacl
   elf32-tilegx-be
   elf64-tilegx-be
   elf32-tilegx-le
   elf64-tilegx-le
   elf32-bigarm
   elf32-bigarm-nacl
   elf32-littlearm
   elf32-littlearm-nacl
   elf64-powerpcle
   elf64-powerpc
   elf32-powerpcle
   elf32-powerpc
   elf64-sparc
   elf32-sparc
   elf32-x86-64
   elf32-x86-64-freebsd
   elf32-x86-64-nacl
   elf64-x86-64
   elf64-x86-64-freebsd
   elf64-x86-64-nacl
   elf32-i386
   elf32-i386-freebsd
   elf32-i386-nacl
  Supported emulations:
   aarch64_elf64_le_vec
   aarch64_elf64_be_vec
   aarch64_elf32_le_vec
   aarch64_elf32_be_vec
   elf64-tradlittlemips
   elf32-tradlittlemips-nacl
   elf64-tradbigmips
   elf32-tradlittlemips-nacl
   elf32-tradlittlemips
   elf32-tradlittlemips-nacl
   elf32-tradbigmips
   elf32-tradlittlemips-nacl
   elf32tilegx_be
   elf64tilegx_be
   elf32tilegx
   elf64tilegx
   armelfb
   armelfb_nacl
   armelf
   armelf_nacl
   elf64lppc
   elf64ppc
   elf32lppc
   elf32ppc
   elf64_sparc
   elf32_sparc
   elf32_x86_64
   elf32_x86_64_nacl
   elf_x86_64
   elf_x86_64_nacl
   elf_i386
   elf_i386_nacl

显然我遗漏了一些重要的配置参数。我还尝试使用较旧的(r8e)Android NDK 的 build/tools/build-gcc.sh 脚本来构建整个编译器工具链,但使用较新的 binutils 版本。这导致了未知的构建错误:

me@linux-vm:/opt/android-ndk-r8e/build/tools$ ./build-gcc.sh --gmp-version=5.0.5 --mpfr-version=3.1.1 --mpc-version=1.0.1 --binutils-version=2.26 
$(pwd)/src $(pwd) arm-linux-androideabi-4.7
To follow build in another terminal, please use: tail -F /tmp/ndk-me/build/toolchain/config.log
Using C compiler: gcc -m32
Using C++ compiler: g++ -m32
Sysroot  : Copying: /opt/android-ndk-r8e/platforms/android-9/arch-arm --> /tmp/ndk-me/build/toolchain/prefix/sysroot
Configure: arm-linux-androideabi-4.7 toolchain build
Building : arm-linux-androideabi-4.7 toolchain [this can take a long time].
Error while building toolchain. See /tmp/ndk-me/build/toolchain/config.log

config.log 的最后条目:

ar cru libintl.a bindtextdom.o dcgettext.o dgettext.o gettext.o finddomain.o loadmsgcat.o localealias.o textdomain.o l10nflist.o explodename.o dcigettext.o dcngettext.o dngettext.o ngettext.o plural.o plural-exp.o localcharset.o relocatable.o localename.o log.o osdep.o intl-compat.o
ranlib libintl.a
make[1]: Leaving directory `/tmp/ndk-me/build/toolchain/libbfd-binutils-2.26/intl'

此时我只是在旋转轮胎并尝试使用配置参数和源包版本的不同组合来蛮力成功。看起来就像为 armelf_linux_eabi 添加仿真支持一样简单,但就像我说的,我找不到任何说明如何执行此操作的文档或指南。肯定有一个 GNU 向导可以为我指明一条更好的道路吗?任何帮助表示赞赏!

【问题讨论】:

    标签: android android-ndk gnu ld binutils


    【解决方案1】:

    我会先尝试--enable-targets=all。这有点像一把大锤子,但也许它可以帮助您避免找出您需要的确切目标三元组(我的猜测是arm-unknown-linux-eabi)。

    【讨论】:

    • 现在我要到某个地方了!谢谢你。这产生了一个工作链接器。在将其安装到我们的构建环境中之前,我必须将其缩减为一组适当的目标,但我暂时将获得这个小小的胜利。
    • 我会给你答案,因为它让我走上了解决这个问题的道路。 binutils/ld 目录中有一个名为“configure.tgt”的文件,它定义了所有目标架构选项的所有受支持的仿真。从此,我能够使用范围更窄的拱形支持对其进行配置。
    猜你喜欢
    • 2012-05-22
    • 1970-01-01
    • 2015-11-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多