前置動作

在開始之前,需要先建立 OpenWRT 在 Ubuntu 上的 Cross Compile 環境,如果還沒有配置的話可以先參考我的另一篇文章:

接下來,下載 OpenSSL 的原始碼,可以直接從 OpenSSL 的官網中下載:連結在此,下載下來之後先解壓縮。

接著執行:

~$ cd openssl-1.1.1h/
~$ ./config no-asm shared --prefix=/usr/local/mipsel

接著我們打開 Makefile 然後尋找這個區段

CROSS_COMPILE=
CC=$(CROSS_COMPILE)gcc
CXX=$(CROSS_COMPILE)g++
CPPFLAGS=
CFLAGS=-Wall -O3
CXXFLAGS=-Wall -O3
LDFLAGS=
EX_LIBS=

會發現一個 CROSS_COMPILE的區段,接著我們按照自己的 Cross Compile 的環境,首先以我的環境,我將 Toolchain 放在:/home/floatflower/Documents/openwrt-sdk, 所以我的編譯器會在/home/floatflower/Documents/openwrt-sdk/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這個位置, 因此我們需要將這個位置放到 CROSS_COMPILE 的欄位中。

要注意的是,OpenWRT 的 Toolchain 的 g++ 和 gcc 會以 mipsel-openwrt-linux-g++ 及 mipsel-openwrt-linux-gcc命名,所以要在 CROSS_COMPILE 中也加上這個 prefix。

因此我們的 Makefile 會變成:

CROSS_COMPILE=/home/floatflower/Documents/openwrt-sdk/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/mipsel-openwrt-linux-

接下來我們要將 Makefile 中的 -m64 全部刪除,然後就可以執行:

~$ sudo make install

這樣就完成了給 OpenWRT 用的 OpenSSL 庫了,這時候我們去 /usr/local 看一下就會發現多了一個 mipsel 資料夾,這樣就確定完成了。

~$ cd /usr/local
~$ ll
...
drwxr-xr-x 7 root root 4.0K  十  20 20:29 mipsel/
...

編譯 Rust 應用程式

這時候我們的 Rust 的應用程式,並且打開 .cargo/config 這個檔案,如果依照上面文章提到的 Cross Compile 的設定,我們的這個 config 文件至少應該會長這樣:

[target.mipsel-unknown-linux-musl]
linker = "mipsel-openwrt-linux-gcc"
ar = "mipsel-openwrt-linux-ar"

接著將 config 檔案改成這樣:

[target.mipsel-unknown-linux-musl]
rustflags = ["-L/usr/local/mipsel/lib"]
linker = "mipsel-openwrt-linux-gcc"
ar = "mipsel-openwrt-linux-ar"

接著我們就可以正式來編譯了:

PKG_CONFIG_ALLOW_CROSS=1 cargo build --target=mipsel-unknown-linux-musl --release

可以注意到這個指令前面加上了一個環境變數 PKG_CONFIG_ALLOW_CROSS 來讓 pkg-config 指令解除 cross compile 的保護,詳細可以參考 Rust 的文件:pkg_config

編譯好之後,這個程式在到 OpenWRT 上的時候就會與路由器中的 OpenSSL 動態函式庫連接。

初次在 OpenWRT 上運行

值得一提的是,如果你是第一次完成這個動作,你把程式放到 OpenWRT 中運行時,可能會遇到一堆錯誤,這裡有幾個指令是必須在 OpenWRT 中先執行的:

~$ opkg install openssl-util # OpenSSL 相關的指令工具
~$ opkg install libopenssl # 安裝 openssl 的函式庫,在這裡要注意的是,在我的 OpenWRT 版本中安裝的 libopenssl 就是 1.1.1 版本的,如果透過這個指令安裝完 openssl 之後,發現不是相同的版本的話,運行上可能會出現錯誤,這時候就需要回到自己的電腦上面重新編譯 openssl 的庫。
~$ opkg install ca-certificates #安裝憑證

這幾個指令是首次運行有 openssl 相關程式時需要先運行的指令。

這樣就可以在 OpenWRT 上面透過 Rust 發出 https 的請求了。