I try to cross-compile a simple rust program with sqlite on Linux for raspberry pi:
Cargo.toml
...
[dependencies]
rusqlite = { version = "0.26.3", features = ["bundled"] }
.cargo/config
[target.arm-unknown-linux-gnueabihf]
linker = "/opt/crosspi/arm-bcm2708/arm-rpi-4.9.3-linux-gnueabihf/bin/arm-linux-gnueabihf-gcc"
When trying to build with cargo build --release --target=arm-unknown-linux-gnueabihf rust bails out with a linker error which basically says:
error: linking with `/opt/crosspi/arm-bcm2708/arm-rpi-4.9.3-linux-gnueabihf/bin/arm-linux-gnueabihf-gcc` failed: exit status: 1
...
= note: /home/hannenz/pidev/projects/kiddyblaster/webui-rust/target/arm-unknown-linux-gnueabihf/release/deps/liblibsqlite3_sys-950993cbbcc1e3eb.rlib(sqlite3.o):(.data.rel.aSyscall+0x58): undefined reference to `fcntl64'
collect2: error: ld returned 1 exit status
(The ... is the full gcc command line, i can post the whole output if relevant)
Without rusqlite cross-compiling works and compiling for the host target is working as well. I also tried the sqlite crate instead of rusqlite, but that produces the exact same linker error.
Would be glad if someone could point me in the right direction what's goiong wrong here.
Cross compiling can be a bit tricky, luckily the cross crate (https://github.com/cross-rs/cross) makes it simple. Follow these steps:
cargo install crossCross.tomlin the root directory (where Cargo.toml is) with this contentBuild the docker container:
docker buildx build --platform linux/arm64 -t my-custom-cross --load .Build your program:
cross build --target aarch64-unknown-linux-gnu --releaseNow you have your binary compiled at
target/aarch64-unknown-linux-gnu/releasedirectoryA bit of explanation
The project
cross-rsprepared all the environment and put it in a docker container. We created our own container based on this (FROM rustembedded/cross:aarch64-unknown-linux-gnu) and we added the extra libraries we need, in this case the dev sqlite3 (apt-get install --assume-yes libsqlite3-dev:arm64).Once our docker container is ready, we configured
crossto use this container by using the fileCross.toml.Depending on your raspberry and the operating system you use in your raspberry, you may need to use other arquitecture. In this case just change
aarch64by yours. In my case I'm using rpi3 64 bit. In case you are using 32 bit or an older board, try something likearm-unknown-linux-gnueabihfor go to the "Supported targets" section in the cross documentation https://github.com/cross-rs/cross.Dont forget to configure
Cross.tomland the Dockerfile to use your target architecture!