I am trying to cross compile my rust program for raspberry pi v3 with sysroot from https://github.com/raspberrypi/tools. But I got the following errors.
error[E0463]: can't find crate for `core`
|
= note: the `armv7-unknown-linux-gnueabihf` target may not be installed
= help: consider downloading the target with `rustup target add armv7-unknown-linux-gnueabihf`
error[E0463]: can't find crate for `compiler_builtins`
error[E0463]: can't find crate for `core`
--> /usr/local/cargo/registry/src/github.com-1ecc6299db9ec823/bitflags-1.3.2/src/lib.rs:282:1
|
282 | pub extern crate core as _core;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ can't find crate
|
= note: the `armv7-unknown-linux-gnueabihf` target may not be installed
= help: consider downloading the target with `rustup target add armv7-unknown-linux-gnueabihf`
For more information about this error, try `rustc --explain E0463`.
error: could not compile `bitflags` due to 3 previous errors
I have checked that armv7-unknown-linux-gnueabihf
has been installed properly. And I don't specify sysroot in cargo config. The error will be gone. Here is my .cargo/config.toml
[target.armv7-unknown-linux-gnueabihf]
linker = "arm-linux-gnueabihf-gcc"
rustflags = ["--sysroot", "/code/pi-tools/arm-bcm2708/arm-bcm2708hardfp-linux-gnueabi/arm-bcm2708hardfp-linux-gnueabi/sysroot"]
Does anyone have experience with cross compile rust with sysroot? The reason why I am using sysroot is that I have some shared libraries that I need to use to compile the rust program. Or what is the standard way of compiling rust in these situation? I am very new to use rust on raspberry pi.
"--sysroot" can not be set in rustflags directly, because rustc compiler will use the parameter and think Rust standard libraries should be search in this sysroot as well. That is why you got the error that crate 'core' can not be found.
The sysroot parameter should be set only when linking with raspberry pi sysroot. so link-arg should be used here. A working example for .cargo/config.toml is:
[target.arm-unknown-linux-gnueabihf]
linker="arm-poky-linux-gnueabi-gcc"
rustflags = [
"-C", "link-arg=-march=armv6",
"-C", "link-arg=-mfpu=vfp",
"-C", "link-arg=-mfloat-abi=hard",
"-C", "link-arg=-mtune=arm1176jzf-s",
"-C", "link-arg=-mfpu=vfp",
"-C", "link-arg=--sysroot=your-sysroot-path",
]
Another way using env instead of .cargo/config.toml is:
/* Used by Rust cross-compilation */
export CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER=${CC_PREFIX}gcc"
export CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_RUSTFLAGS="-C link-arg=-mcpu=cortex-a72.cortex-a53 -C link-arg=-march=armv8-a+crc -C link-arg=--sysroot=${TARGET_SYSROOT}"
export CARGO_BUILD_TARGET=aarch64-unknown-linux-gnu
Then "cargo build" will do cross compilation for the target CARGO_BUILD_TARGET.
Note: The two environment names CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER/CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_RUSTFLAGS should be changed to your own target architecture. So if target is armv7-unknown-linux-gnueabihf, the environment variable should be CARGO_TARGET_ARMV7_UNKNOWN_LINUX_GNUEABIHF_LINKER.
One cross-compilation example in rustc document for reference.