rust 交叉編譯樹莓派程序
使用 rust 寫樹莓派程序時,如果直接在樹莓派上進行編譯,速度非常慢,如果是 zero 那更加是慢到受不了。因此最好是能通過開發機編譯完后,直接放到樹莓派上運行。
由於開發機上的 cpu 架構、操作系統和目標機不同,開發機通常是 x86 架構,系統可以是 mac、linux、windows,而樹莓派則為 armv6 或 armv7 的 linux 系統。未經過特殊處理,默認的編譯工具鏈編譯出的程序只適合開發機上運行,為特定目標編譯需要一套別的編譯工具鏈,這種方法被稱為交叉編譯 cross compilation。
要注意,不同版本的樹莓派的 cpu 架構不一樣,具體可查看
cat /proc/cpuinfo
mac 上進行交叉編譯
現在已經有開發者把交叉編譯工具做個 brew 安裝腳本,安裝
brew install FiloSottile/musl-cross/musl-cross --without-x86_64 --with-arm-hf
這個交叉編譯工具使用的是 musl c 庫,跨平台,性能比 glibc 要差一點。
然后通過 rustup 安裝不同的目標支持
rustup target add arm-unknown-linux-musleabihf # armv6
rustup target add armv7-unknown-linux-musleabihf # armv7
linux 上進行交叉編譯
linux 上交叉編譯時有個不大不小的陷阱,在 ubuntu 源內的編譯工具鏈,僅支持 armv7 的編譯,不支持 armv6 ,導致編譯出來的東西無法在 pi zero 上運行。
因此,需要下載一個支持 armv6 的工具鏈,慶幸的是 https://musl.cc/ 已經做了這些工作,基於 musl 庫做了預編譯。
首先下載合適的的工具包,並解壓。(除了 arm-linux-musleabihf-cross,在 https://more.musl.cc 還有其它的架構)
查看 arm-linux-musleabihf-cross
目錄,在 bin 下可看到所有的預編譯工具。可以把整個解壓后的包放到 /opt 目錄下,作為日常附加的工具,並在 .bashrc 中修改 PATH 路徑
wget https://more.musl.cc/$(uname -m)-linux-musl/arm-linux-musleabihf-cross.tgz
tar -xvf arm-linux-musleabihf-cross.tgz
sudo mv arm-linux-musleabihf-cross /opt/
echo 'PATH=/opt/arm-linux-musleabihf-cross/bin:$PATH' >> ~/.bashrc
source ~/.bashrc
然后通過 rustup 安裝不同的目標支持
rustup target add arm-unknown-linux-musleabihf # armv6
rustup target add armv7-unknown-linux-musleabihf # armv7
編譯設置
在項目下創建一個 .cargo/config
文件,內容為
[target.arm-unknown-linux-musleabihf]
linker = "arm-linux-musleabihf-ld"
[target.armv7-unknown-linux-musleabihf]
linker = "arm-linux-musleabihf-ld"
然后用按照不同的開發機、目標機類型,使用 cargo 進行編譯
cargo build --target arm-unknown-linux-musleabihf --release # armv6
cargo build --target armv7-unknown-linux-musleabihf --release # armv7
編譯完后,在 target/<目標類型>/release
中可找到對應的可執行文件,copy 到目標上就可以運行。
這個文件也可使用 strip 工具來刪掉一些符號,從而減少整個可執行文件的體積。