9

我正在尝试交叉编译一个 rust 项目,arm-linux-musleabihf并且在使用musl-cross-make. rust 项目有一个依赖项libgit2,这似乎是导致问题的依赖项。

使用:

  • 最新的 rust (1.43.1 via rustup)
  • arm-unknown-linux-musleabihf目标_
  • 最新musl-cross-makeTARGET=arm-linux-musleabihf
  • 指向TARGET_CC_linux_arm-unknown-linux-musleabihfCARGO_TARGET_ARM_UNKNOWN_LINUX_MUSLEABIHF_LINKER/opt/musl-cross-make/output/bin/arm-linux-musleabihf-gcc

构建时出现错误:

error: linking with `/opt/musl-cross-make/output/bin/arm-linux-musleabihf-gcc` failed: exit code: 1
...
  = note: /opt/musl-cross-make/output/bin/../lib/gcc/arm-linux-musleabihf/9.2.0/../../../../arm-linux-musleabihf/bin/ld: /tmp/rustcvSvGAJ/liblibgit2_sys-e56c2f9bd024a0a9.rlib(odb.o): in function `git_odb__add_default_backends':
          odb.c:(.text.git_odb__add_default_backends+0x24): undefined reference to `__stat_time64'
          /opt/musl-cross-make/output/bin/../lib/gcc/arm-linux-musleabihf/9.2.0/../../../../arm-linux-musleabihf/bin/ld: /tmp/rustcvSvGAJ/liblibgit2_sys-e56c2f9bd024a0a9.rlib(config.o): in function `git_config_add_file_ondisk':
          config.c:(.text.git_config_add_file_ondisk+0x34): undefined reference to `__stat_time64'
          /opt/musl-cross-make/output/bin/../lib/gcc/arm-linux-musleabihf/9.2.0/../../../../arm-linux-musleabihf/bin/ld: /tmp/rustcvSvGAJ/liblibgit2_sys-e56c2f9bd024a0a9.rlib(config_file.o): in function `config_file_read':
          config_file.c:(.text.config_file_read+0x48): undefined reference to `__stat_time64'
...etc...

链接器似乎难以解析特定于 musl 的time64符号,目前尚不清楚原因。

如果:

  • x86_64-linux-musl在 rust 和musl-cross-make
  • musl-cross-makeMUSL_VER=1.1.24

time我还编写了一个同时使用和的小 C 程序,它stat基于交叉编译器上的 musl 1.2.0 构建,没有任何问题。

这里发生了什么?libgit2这意味着它找不到正确的__time64符号有什么特别之处?

4

3 回答 3

7

问题在于,Rust 1.44 及以下版本附带的 MUSL libc 是基于 MUSL libc 1.1.X 的,而不是 1.2.0。

Rust 构建 libgit2 的时候也需要构建 libgit2-sys,也就是 C 代码。在构建 libgit2-sys 时,它使用您使用 musl-cross-make 自己构建和安装的 MUSL libc 版本。默认情况下这是 1.2.0,它重新设计了time_t 32/64位支持,依赖于__stat_time64和其他各种类似命名的方法(例如__time64)。

然而,当 Rust 链接你的最终应用程序时,它使用的是 Rust 附带的用于 x86_64-linux-musl 目标的 MUSL libc 版本,它不包括新的 time_t 支持,也没有__stat_time64,__time64等。所以链接失败。

现在你有两个选择:

  • 使用 musl-cross-make 构建 1.1.24 的 MUSL lib。我不是 100% Rust 1.44 包含什么版本。它可能是 1.1.22,尽管从我自己的测试中我发现 1.1.24 工作得很好(就像你一样)。
  • 使用您自己的 MUSL libc 版本构建您自己的 Rust 版本和/或目标 liblibc.rlib。我自己从来没有成功地做到这一点,尽管如果你想尝试这个,这可能是一个很好的起点。

正在解决使用 Rust 附带的 libc 而不是本地提供的版本的一般问题,例如这里

于 2020-06-23T19:54:44.660 回答
3

您可以尝试https://github.com/richfelker/libcompat_time32中列出的说明:

添加-Wl,--whole-archive -lcompat_time32 -Wl,--no-whole-archive到链接命令行。如果 libtool 正在拦截和修改命令行,则可能需要特殊的 hack(例如添加-Wl,到)。-lcompat_time32

于 2020-06-01T15:02:15.360 回答
0

我建议尝试https://github.com/rust-embedded/cross:它为 docker 中的交叉编译设置环境并无缝工作,即使对于此处突出显示的情况也是如此。

AFAICT,他们用正确的版本重新编译 musl。

于 2021-11-19T16:22:28.910 回答