在 Ubuntu 上將 Rust 應用程式 Cross Compile 到 OpenWRT 上執行
在這篇文章中將講解如何將 rust 的應用程式透過 cross compile 的方式, 編譯成給運行 OpenWRT 的路由器, 因為自己在嘗試編譯的時候撞了好幾個小時的牆, 所以寫了這篇文章把方法分享出來。
事前準備
下載 OpenWRT SDK
在開始之前,請先確定自己手上的路由器的 CPU 種類已經可用版本,以我的路由器為例 ASUS AC51U 為例:
- Current Release 為 19.07.3,但是我是好幾個月前安裝的,所以我的版本是 19.07.1,因此稍後的示範會以 19.07.1 為例。
- SoC 的型號為 MediaTek MT7620A,platform 為 ramips。
接著我們從這個網站 https://downloads.openwrt.org/releases/ 去找到相對應的 SDK,以我的為例就是:
19.07.1/ > targets/ > ramips/ > mt7620/ > openwrt-imagebuilder-19.07.1-ramips-mt7620.Linux-x86_64.tar.xz
然後我們將這個 SDK 的壓縮檔下載下來、解壓縮,並將這個 SDK 的 staging_dir 存到 PATH 中待稍後使用:
~$ cd ~
~$ wget https://downloads.openwrt.org/releases/19.07.1/targets/ramips/mt7620/openwrt-sdk-19.07.1-ramips-mt7620_gcc-7.5.0_musl.Linux-x86_64.tar.xz
~$ tar -xvf openwrt-sdk-19.07.1-ramips-mt7620_gcc-7.5.0_musl.Linux-x86_64.tar.xz
~$ PATH=$PATH:~/openwrt-sdk-19.07.1-ramips-mt7620_gcc-7.5.0_musl.Linux-x86_64/staging_dir/toolchain-mipsel_24kc_gcc-7.5.0_musl/bin
~$ export PATH
~$ echo $PATH # 檢查一下 PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/root/openwrt-sdk-19.07.1-ramips-mt7620_gcc-7.5.0_musl.Linux-x86_64/staging_dir/toolchain-mipsel_24kc_gcc-7.5.0_musl/bin
安裝 rustup
如果你先前是用apt install
來安裝 rustc 或是 cargo 的話,那麼可能要請你先移除,否則的話 rustup 在添加工具鏈 (toolchain) 不會添加到由apt install
安裝的 rustc 上,這樣會導致編譯失敗。
在一個完全沒有 rust 的環境下,直接執行:
~$ sudo snap install rustup --classic
這個指令執行完之後就會同時擁有rustc
、rustup
以及cargo
了
將 toolchain 透過 rustup 加進來
接著我們執行指令:
~$ rustup install stable # 安裝 stable 的 rust
~$ rustup default stable
~$ rustup target add mipsel-unknown-linux-musl
編譯 Cargo 專案
新建 cargo 專案
~$ cargo new rust-openwrt
Created binary (application) `rust-openwrt` package
~$ cd rust-openwrt
~$ mkdir .cargo
~$ touch .cargo/config
接著我們在.cargo/config
文件中輸入:
[target.mipsel-unknown-linux-musl]
linker = "mipsel-openwrt-linux-gcc"
ar = "mipsel-openwrt-linux-ar"
編譯專案
這樣就設定好了,接著我們執行編譯指令:
~$ cargo build --target=mipsel-unknown-linux-musl
Compiling rust-openwrt v0.1.0 (/root/rust-openwrt)
Finished dev [unoptimized + debuginfo] target(s) in 0.56s
將編譯好的執行檔上傳到路由器
~$ scp rust-openwrt root@192.168.1.1:/
上傳完畢之後我們就透過 ssh 登入路由器,並找到剛才上傳的檔案
~$ ssh root@192.168.1.1
BusyBox v1.30.1 () built-in shell (ash)
_______ ________ __
| |.-----.-----.-----.| | | |.----.| |_
| - || _ | -__| || | | || _|| _|
|_______|| __|_____|__|__||________||__| |____|
|__| W I R E L E S S F R E E D O M
-----------------------------------------------------
OpenWrt 19.07.1, r10911-c155900f66
-----------------------------------------------------
~$ cd /
~$ ./rust-openwrt
Hello, world!
這樣我們在 OpenWRT 的作業系統上的 Hello World 就完成了。