我试图交叉编译一个arm-linux-musleabihf的rust项目,但在使用musl-cross-make时遇到了一个链接器错误.rust项目依赖于libgit2,这似乎是导致问题的原因.

使用:

  • 最新 rust 蚀(1.43.1至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个符号,原因尚不清楚.

如果:

  • 我在rust和musl-cross-make上都使用了x86_64-linux-musl目标
  • 我用MUSL_VER=1.1.24musl-cross-make

我还编写了一个使用timestat的小C程序,它在交叉编译器的musl 1.2.0上构建,没有任何问题.

这是怎么回事?libgit2有什么特别之处,这意味着它找不到正确的__time64个符号?

推荐答案

问题在于,在1.44之前(含1.44)版本的Rust版本中提供的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等.因此链接失败.

现在你有两个 Select :

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

目前正在研究使用Rust 的libc而不是本地提供的版本的一般问题,例如here.

Rust相关问答推荐

Rust TcpStream不能在读取后写入,但可以在不读取的情况下写入.为什么?

如何在Rust中表示仅具有特定大小的数组

如何使用 list 在Rust for Windows中编译?

MPSC频道在接收器处阻塞

如何实现泛型枚举的`Serde::Desialize`特性

同时从不同线程调用DLL的不同函数会出现分段错误或产生STATUS_STACK_BUFFER_OVERRUN

函数内模块的父作用域的访问类型

铁 rust 中的泛型:不能将`<;T作为添加>;::Output`除以`{Float}`

Trait bound i8:来自u8的不满意

Rust函数的返回值不能引用局部变量或临时变量

根据填充系数以相对大小在给定空间中布局项目

可选包装枚举的反序列化

注释闭包参数强调使用高阶排定特征界限

有什么方法可以通过使用生命周期来减轻嵌套生成器中的当生成器产生时borrow 可能仍在使用错误?

std::vector::shrink_to_fit 如何在 Rust 中工作?

切片不能被 `usize` 索引?

使用 rust 在 google cloud run (docker) 中访问环境变量的适当方法

当我不满足特征界限时会发生什么?

通用类型,不同于输入类型,作为函数的返回值

如何从 Rust 应用程序连接到 Docker 容器中的 SurrealDB?