在树莓派上玩转 Rust :交叉编译

本文面向于对 Rust 和 Linux 有一定基础的读者。

在开始之前,请先确保你已经拥有了一个树莓派,和一台装有 Linux 的物理机或者虚拟机,装好 Rust,并且已经为树莓派刷好了系统(推荐官方系统),能够在你电脑上用 ssh 连接至树莓派。期间你可能会遇到问题,请尝试从文末给出的连接找到答案。

通常,要得到可在树莓派上运行的二进制文件有两种方式。一种是在树莓派上安装 Rust,编译源码并运行。由于树莓派硬件资源的限制,在树莓派上编译 Rust 极其缓慢,尤其是在 zero w 这类型号上,并且编写源码也是件麻烦的事。另一种是在你的电脑上编写源码,交叉编译,并通过 scp 命令发送至树莓派。在开发时,你也可以利用 rsync 工具,将编译好的二进制文件同步至树莓派。

为了能够在你电脑上交叉编译 Rust,我们可以用 rustup 安装相应的 target。用 ssh 连接至你的树莓派 ,执行 uname -m 命令:

$ uname -m
armv7l // or aarch64

如果是 armv7l ,就用 rustup 安装 armv7-unknown-linux-musleabihf

$ rustup target add armv7-unknown-linux-musleabihf

如果是 aarch64,就用 rustup 安装 aarch64-unknown-linux-musl

$ rustup target add aarch64-unknown-linux-musl

这还没完,由于 Rust 使用了系统提供的连接器,我们还需要去 https://musl.cc/ 下载 armv7l-linux-musleabihf-cross.tgzaarch64-linux-musl-cross.tgz,将其解压,并将 bin 目录添加至环境变量(例如 ~/.profile 文件):

export PATH="$HOME/code/tool/armv7l-linux-musleabihf-cross/bin:$PATH"
// or
export PATH="$HOME/code/tool/aarch64-linux-musl-cross/bin:$PATH"

验证是否添加正确:

$ source ~/.profile
$ armv7l-linux-musleabihf-gcc -v
// or
$ aarch64-linux-musl-gcc -v
...
gcc version 9.2.1 20190831 (GCC) 

如果你看到了一长串信息,最后还带有版本号,那说明没问题。为什么是 musl 而不是 gnu 呢?因为在 gnu 工具链下,Rust 默认动态链接 libc,为了避免交叉编译出现问题,首选 musl

接下来,创建一个 Rust 项目:

$ cargo new hello
     Created binary (application) `hello` package
$ cd hello

在项目根目录创建 .cargo 目,并在其中创建名为 config 的文件,写入:

[target.armv7-unknown-linux-musleabihf]
linker = "armv7l-linux-musleabihf-gcc"

[target.aarch64-unknown-linux-musl]
linker = "aarch64-linux-musl-gcc"
rustflags = ["-C", "target-feature=+crt-static", "-C", "link-arg=-lgcc"]

补充:

你也可以在系统上安装并使用gcc-arm-linux-gnueabihfgcc-aarch64-linux-gnu,对应的,上面的 linker 应该填 arm-linux-gnueabihf-gccaarch64-linux-gnu-gcc

编译:

$ cargo build --target=armv7-unknown-linux-musleabihf
// or
$ cargo build --target=aarch64-unknown-linux-musl
    Finished dev [unoptimized + debuginfo] target(s) in 0.02s

将编译出的目标文件复制到树莓派:

$ scp target/armv7-unknown-linux-musleabihf/debug/hello pi@192.168.124.15:/home/pi
// or
scp target/aarch64-unknown-linux-musl/debug/hello pi@192.168.124.7:/home/pi

运行:

pi@raspberrypi:~ $ ./hello 
Hello, world!

资源:

Etcher

https://www.raspberrypi.org/downloads/

树莓派 Raspberry Pi 设置无线上网

树莓派开启SSH的N种方法

树莓派实验室

https://rustup.rs/

https://forge.rust-lang.org/release/platform-support.html

https://musl.cc/

https://github.com/japaric/rust-cross

https://doc.rust-lang.org/reference/linkage.html

Cannot cross-compile aarch64-musl on x86_64 linux

发表评论

电子邮件地址不会被公开。 必填项已用*标注

+ 65 = 71