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

image-20210511083744831

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

image-20210511102911719

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

image-20210511083639483

一个 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

参考文档

发表于: 作者:JiapengLi
由于某种不存在的原因,评论区正在努力加载中……