1

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.

Herohtar
  • 5,347
  • 4
  • 31
  • 41

1 Answers1

1

Cross compiling can be a bit tricky, luckily the cross crate (https://github.com/cross-rs/cross) makes it simple. Follow these steps:

  • Install cargo cross: cargo install cross
  • Create a file called Cross.toml in the root directory (where Cargo.toml is) with this content
[target.aarch64-unknown-linux-gnu]
image = "my-custom-cross"
  • Create a Dockerfile with this content
FROM rustembedded/cross:aarch64-unknown-linux-gnu

RUN dpkg --add-architecture arm64 && \
    apt-get update && \
    apt-get install --assume-yes libsqlite3-dev:arm64
  • Build the docker container: docker buildx build --platform linux/arm64 -t my-custom-cross --load .

  • Build your program: cross build --target aarch64-unknown-linux-gnu --release

Now you have your binary compiled at target/aarch64-unknown-linux-gnu/release directory

A bit of explanation

The project cross-rs prepared 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 cross to use this container by using the file Cross.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 aarch64 by yours. In my case I'm using rpi3 64 bit. In case you are using 32 bit or an older board, try something like arm-unknown-linux-gnueabihf or go to the "Supported targets" section in the cross documentation https://github.com/cross-rs/cross.

Dont forget to configure Cross.toml and the Dockerfile to use your target architecture!

Álvaro García
  • 431
  • 2
  • 7