I'm trying to cross-compile a rust project for arm-linux-musleabihf
and am hitting a linker error when using musl-cross-make
. The rust project has a dependency on libgit2
and this is the dependency that seems to be causing the problem.
Using:
rustup
)arm-unknown-linux-musleabihf
targetmusl-cross-make
with TARGET=arm-linux-musleabihf
TARGET_CC_linux_arm-unknown-linux-musleabihf
and CARGO_TARGET_ARM_UNKNOWN_LINUX_MUSLEABIHF_LINKER
at /opt/musl-cross-make/output/bin/arm-linux-musleabihf-gcc
I get an error when building:
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...
It looks like the linker is having difficulty resolving the musl-specific time64
symbols, and it's not clear why.
This works fine if:
x86_64-linux-musl
target on both rust and musl-cross-make
musl-cross-make
with MUSL_VER=1.1.24
I also wrote a little C program that uses both time
and stat
, and this builds on musl 1.2.0 on the cross compiler without any issue.
What's going on here? What's special about libgit2
which means that it can't find the right __time64
symbols?
The problem is that the MUSL libc that ships with Rust versions up to and including 1.44 is MUSL libc 1.1.X based, not 1.2.0.
When Rust builds libgit2 is also needs to build libgit2-sys, which is C code. When building libgit2-sys it uses the MUSL libc version that you've built and installed yourself with musl-cross-make. This is 1.2.0 by default, which has reworked time_t 32/64
bit support, having a dependency on __stat_time64
and various other similarly named methods (such as __time64
).
However, when Rust is linking your final application it is using the version of MUSL libc shipped with Rust for the x86_64-linux-musl target, which doesn't include that new time_t support, and doesn't have __stat_time64
, __time64
, etc. So the link fails.
Right now you have 2 options:
The general issue of using libc shipped with Rust, instead of a locally provided version, is being worked on, e.g. here.
You could try the instructions listed in https://github.com/richfelker/libcompat_time32:
Add
-Wl,--whole-archive -lcompat_time32 -Wl,--no-whole-archive
to the link command line. Special hacks (like prepending-Wl,
to-lcompat_time32
) may be needed if libtool is intercepting and mangling the command line.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With