Helium gateway-rs 编译
1. 环境搭建
# rust
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
# cargo
cargo install cross
cargo install cargo-make
# 增加平台
rustup target add armv7-unknown-linux-musleabihf
rustup target add arm-unknown-linux-gnueabihf
# Supports Pi 0/1
rustup target add arm-unknown-linux-gnueabihf
# Supports Pi 2/3/4
rustup target add armv7-unknown-linux-gnueabihf
2. 编译
查看 rustc 支持的目标平台:
> rustc --print target-list | pr -tw120 --output-tabs=' 1' --columns 3
aarch64-apple-darwin i586-unknown-linux-gnu riscv64gc-unknown-none-elf
aarch64-apple-ios i586-unknown-linux-musl riscv64imac-unknown-none-elf
aarch64-apple-ios-macabi i686-apple-darwin s390x-unknown-linux-gnu
aarch64-apple-ios-sim i686-linux-android s390x-unknown-linux-musl
aarch64-apple-tvos i686-pc-windows-gnu sparc-unknown-linux-gnu
aarch64-fuchsia i686-pc-windows-msvc sparc64-unknown-linux-gnu
aarch64-linux-android i686-unknown-freebsd sparc64-unknown-netbsd
aarch64-pc-windows-msvc i686-unknown-haiku sparc64-unknown-openbsd
aarch64-unknown-freebsd i686-unknown-linux-gnu sparcv9-sun-solaris
aarch64-unknown-hermit i686-unknown-linux-musl thumbv4t-none-eabi
aarch64-unknown-linux-gnu i686-unknown-netbsd thumbv6m-none-eabi
aarch64-unknown-linux-gnu_ilp32 i686-unknown-openbsd thumbv7a-pc-windows-msvc
aarch64-unknown-linux-musl i686-unknown-uefi thumbv7a-uwp-windows-msvc
aarch64-unknown-netbsd i686-uwp-windows-gnu thumbv7em-none-eabi
aarch64-unknown-none i686-uwp-windows-msvc thumbv7em-none-eabihf
aarch64-unknown-none-softfloat i686-wrs-vxworks thumbv7m-none-eabi
aarch64-unknown-openbsd mips-unknown-linux-gnu thumbv7neon-linux-androideabi
aarch64-unknown-redox mips-unknown-linux-musl thumbv7neon-unknown-linux-gnueabihf
aarch64-uwp-windows-msvc mips-unknown-linux-uclibc thumbv7neon-unknown-linux-musleabihf
aarch64-wrs-vxworks mips64-unknown-linux-gnuabi64 thumbv8m.base-none-eabi
aarch64_be-unknown-linux-gnu mips64-unknown-linux-muslabi64 thumbv8m.main-none-eabi
aarch64_be-unknown-linux-gnu_ilp32 mips64el-unknown-linux-gnuabi64 thumbv8m.main-none-eabihf
arm-linux-androideabi mips64el-unknown-linux-muslabi64 wasm32-unknown-emscripten
arm-unknown-linux-gnueabi mipsel-sony-psp wasm32-unknown-unknown
arm-unknown-linux-gnueabihf mipsel-unknown-linux-gnu wasm32-wasi
arm-unknown-linux-musleabi mipsel-unknown-linux-musl x86_64-apple-darwin
arm-unknown-linux-musleabihf mipsel-unknown-linux-uclibc x86_64-apple-ios
armebv7r-none-eabi mipsel-unknown-none x86_64-apple-ios-macabi
armebv7r-none-eabihf mipsisa32r6-unknown-linux-gnu x86_64-apple-tvos
armv4t-unknown-linux-gnueabi mipsisa32r6el-unknown-linux-gnu x86_64-fortanix-unknown-sgx
armv5te-unknown-linux-gnueabi mipsisa64r6-unknown-linux-gnuabi64 x86_64-fuchsia
armv5te-unknown-linux-musleabi mipsisa64r6el-unknown-linux-gnuabi64 x86_64-linux-android
armv5te-unknown-linux-uclibceabi msp430-none-elf x86_64-pc-solaris
armv6-unknown-freebsd nvptx64-nvidia-cuda x86_64-pc-windows-gnu
armv6-unknown-netbsd-eabihf powerpc-unknown-linux-gnu x86_64-pc-windows-msvc
armv7-apple-ios powerpc-unknown-linux-gnuspe x86_64-sun-solaris
armv7-linux-androideabi powerpc-unknown-linux-musl x86_64-unknown-dragonfly
armv7-unknown-freebsd powerpc-unknown-netbsd x86_64-unknown-freebsd
armv7-unknown-linux-gnueabi powerpc-unknown-openbsd x86_64-unknown-haiku
armv7-unknown-linux-gnueabihf powerpc-wrs-vxworks x86_64-unknown-hermit
armv7-unknown-linux-musleabi powerpc-wrs-vxworks-spe x86_64-unknown-illumos
armv7-unknown-linux-musleabihf powerpc64-unknown-freebsd x86_64-unknown-l4re-uclibc
armv7-unknown-netbsd-eabihf powerpc64-unknown-linux-gnu x86_64-unknown-linux-gnu
armv7-wrs-vxworks-eabihf powerpc64-unknown-linux-musl x86_64-unknown-linux-gnux32
armv7a-none-eabi powerpc64-wrs-vxworks x86_64-unknown-linux-musl
armv7a-none-eabihf powerpc64le-unknown-linux-gnu x86_64-unknown-netbsd
armv7r-none-eabi powerpc64le-unknown-linux-musl x86_64-unknown-none-hermitkernel
armv7r-none-eabihf riscv32gc-unknown-linux-gnu x86_64-unknown-none-linuxkernel
armv7s-apple-ios riscv32gc-unknown-linux-musl x86_64-unknown-openbsd
asmjs-unknown-emscripten riscv32i-unknown-none-elf x86_64-unknown-redox
avr-unknown-gnu-atmega328 riscv32imac-unknown-none-elf x86_64-unknown-uefi
hexagon-unknown-linux-musl riscv32imc-unknown-none-elf x86_64-uwp-windows-gnu
i386-apple-ios riscv64gc-unknown-linux-gnu x86_64-uwp-windows-msvc
i586-pc-windows-msvc riscv64gc-unknown-linux-musl x86_64-wrs-vxworks
gateway-rs 使用到的平台
CROSS_TARGET = "arm-unknown-linux-gnueabihf" # raspberry pi 0 / 1
CROSS_TARGET = "armv7-unknown-linux-gnueabihf" # raspberry pi 2 / 3 / 4
CROSS_TARGET = "armv7-unknown-linux-musleabihf" # kerlink
CROSS_TARGET = "mipsel-unknown-linux-musl" # ramips
CROSS_TARGET = "mips-unknown-linux-musl"
CROSS_TARGET = "armv5te-unknown-linux-musleabi"
编译未通过
随便选择一个 target,尝试编译,但是报错,由于缺少工具链。参考 https://github.com/japaric/rust-cross 解决。
> cargo build --target armv7-unknown-linux-musleabihf --release
3. 配置交叉编译工具链
交叉编译工具链是一个麻烦事儿
命名规范
交叉编译工具链的命名规则为:arch [-vendor] [-os] [-(gnu)eabi]
- arch - 体系架构,如ARM,MIPS
- verdor - 工具链提供商
- os - 目标操作系统
- eabi - 嵌入式应用二进制接口
根据对操作系统的支持与否,ARM GCC可分为支持和不支持操作系统,如:
- arm-none-eabi:这个是没有操作系统的(bare metal),自然不可能支持那些跟操作系统关系密切的函数,比如fork。他使用的是newlib这个专用于嵌入式系统的C库。
- arm-none-linux-eabi:用于Linux的,使用Glibc
参考:https://blog.csdn.net/weixin_43997099/article/details/109087458
gcc-arm-linux-gnueabi 以及 gcc-arm-linux-gnueabihf 的区别
gcc-arm-linux-gnueabi is the cross-toolchain package for the armel architecture. This toolchain implies the EABI generated by gcc's -mfloat-abi=soft or -mfloat-abi=softfp options.
gcc-arm-linux-gnueabihf is the cross-toolchain package for the armhf architecture. This toolchain implies the EABI generated by the gcc -mfloat-abi=hard option.
hf
将开启硬件浮点指令,可能有厂家会从成本角度考虑阉割硬件浮点数预算的支持,这样就必须使用软件浮点数。
树莓派工具链
git clone --depth 1 https://github.com/raspberrypi/tools.git rpitools
~/tool/rpitools/arm-bcm2708/arm-linux-gnueabihf/bin
4. 为 DietPi 系统编译 gateway-rs
工具链
下载 rpi 官方的工具链,并添加环境变量。
PATH=...:...:/home/jp/tool/rpitools/arm-bcm2708/arm-rpi-4.9.3-linux-gnueabihf/bin/
修改 cargo 配置文件指定 linker 及其配置
仓库 .cargo/config.toml
路径下面有相关的配置文件。可以根据 target 准备编译选项和链接配置参数。增加如下配置:
...
# Pi 2/3/4
[target.armv7-unknown-linux-gnueabihf]
linker = "arm-linux-gnueabihf-gcc"
rustflags = [
"-C", "target-feature=+crt-static",
"-C", "link-args=-static",
]
...
编译并运行
> cargo build --target armv7-unknown-linux-gnueabihf --release
Compiling libc v0.2.94
Compiling proc-macro2 v1.0.26
Compiling unicode-xid v0.2.2
Compiling syn v1.0.72
Compiling cfg-if v1.0.0
Compiling autocfg v1.0.1
Compiling version_check v0.9.3
Compiling getrandom v0.2.2
...
...
...
Compiling tonic v0.4.3
Compiling gateway-rs v1.0.0-alpha.8 (/home/jp/helium/gateway-rs)
Finished release [optimized] target(s) in 1m 35s
上传 (使用 tar / pipe / ssh 方式进行)
> tar cf - ./target/armv7-unknown-linux-gnueabihf/release/helium_gateway | ssh root@192.168.0.21 "tar xf - -C ~"
运行
root@DietPi:~/target/armv7-unknown-linux-gnueabihf/release# ./helium_gateway -h
helium_gateway 1.0.0-alpha.8
Helium Light Gateway
USAGE:
helium_gateway [FLAGS] [OPTIONS] <SUBCOMMAND>
FLAGS:
--daemon Daemonize the application
-h, --help Prints help information
-V, --version Prints version information
OPTIONS:
-c <config> Configuration folder to use. default.toml will be loaded first and any custom settings in
settings.toml merged in [default: /etc/helium_gateway]
SUBCOMMANDS:
help Prints this message or the help of the given subcommand(s)
key Commands on gateway keys
server Run the gateway service
update Commands for gateway updates
注意:dietpi 一定需要增加静态编译的选项,否则编译后的镜像无法使用(可能是 dietpi 比较精简删掉了一些动态库,测试用的dietpi 版本 7.)
> ssh root@192.168.0.21 root@192.168.0.21's password: ───────────────────────────────────────────────────── DietPi v7.1.2 : 06:35 - Wed 05/12/21 ───────────────────────────────────────────────────── - Device model : RPi 3 Model B (aarch64) - CPU temp : 48'C : 118'F (Optimal temperature) - LAN IP : 192.168.0.21 (eth0) - MOTD : Did you know that you can run "dietpi-banner" to change its content? ───────────────────────────────────────────────────── DietPi Team : MichaIng (lead), Daniel Knight (founder), Joulinar (support) Image by : DietPi Core Team (pre-image: Raspberry Pi OS Lite (64-bit)) Web : https://dietpi.com | https://twitter.com/DietPi_ Patreon Legends : Camry2731 Contribute : https://dietpi.com/contribute.html DietPi Hosting : Powered by https://myvirtualserver.com dietpi-launcher : All the DietPi programs in one place. dietpi-config : Feature rich configuration tool for your device. dietpi-software : Select optimized software for installation. htop : Resource monitor. cpu : Shows CPU information and stats.
小贴士
pr
为了解决终端内容复制到 md 后格式混乱的问题(TAB 默认宽度不一样),help 文档不是很友好,就稍微阅读了一下 pr 的源码。
默认使用 TAB (8)进行排版, --output-tabs=' 1'
(1前面有个空格) 选项可以强制使用空格输出。
pr 工具隶属于 gnu core utilities。
一个 windows 工具链下载站
https://gnutoolchains.com/raspberry/
神秘的 musl
官方网站:https://www.musl-libc.org/ / https://musl.libc.org/
musl is an implementation of the C standard library built on top of the Linux system call API, including interfaces defined in the base language standard, POSIX, and widely agreed-upon extensions. musl is ightweight, fast, simple, free, and strives to be correct in the sense of standards-conformance and safety.
标有 musl 字样的 target 表示的应该是有 musl libc 依赖的 gcc。而标有 gnu 字样的应该是以来 glibc 的库。 (仅为猜测)
限制 cargo 编译时的任务数
$ export CARGO_BUILD_JOBS = 1
$ cargo build