我之前寫過一篇文章介紹如何在 Windows 下編譯適用於 Linux 的 Rust 程序,不過 Rust 原生的配置方法並不算簡單,今天我想介紹一個更簡單的方法來編譯 Rust 程序到 MacOS 和 Linux。同理,也可以在這些平台上編譯到 Windows。
Cross-rs#
Cross-rs是一個 Rust 的交叉編譯工具,在依賴不複雜的情況下,幾乎能夠一條指令就將 Rust 程序編譯到其他平台。它的原理是使用 Docker 來運行交叉編譯的工具鏈,因此需要機子上有 Docker 或 Podman。這個庫也支持測試,這不是本文章關注的內容,因此只在這提一下。
安裝#
值得注意的是,由於這個項目依賴 Docker,所以在編譯時需要保持網絡暢通,Docker Hub 的鏡像下載速度可能會很慢,建議使用你能快速訪問的鏡像源。
在確保 Rust 工具鏈、Docker 或 Podman 已經安裝的情況下,使用以下命令安裝 cross:
cargo install cross --git https://github.com/cross-rs/cross
基本用法#
對於簡單的項目,安裝完成後就可以直接使用 cross 來編譯了:
# 編譯到目標架構是x86_64的Linux
cross build --target x86_64-unknown-linux-gnu --release
# 編譯到目標架構是aarch64的Linux
cross build --target aarch64-unknown-linux-gnu --release
這裡以我以前練手寫的一個Socks5 代理軟件為例,編譯結果如下:
cross build --target x86_64-unknown-linux-gnu --release
# info: syncing channel updates for 'stable-x86_64-unknown-linux-gnu'
# info: latest update on 2025-03-18, rust version 1.85.1 (4eb161250 2025-03-15)
# info: downloading component 'cargo'
# ......
# info: checking for self-update
# info: downloading component 'rust-src'
# info: installing component 'rust-src'
# Unable to find image 'ghcr.io/cross-rs/x86_64-unknown-linux-gnu:main' locally
# main: Pulling from cross-rs/x86_64-unknown-linux-gnu
# d9802f032d67: Pull complete
# ......
# b4f2b8f6bece: Pull complete
# Digest: sha256:e01aa4c146da3834f49ead052f7f9b9cff95e3dd576f909c87cea473bba84e1b
# Status: Downloaded newer image for ghcr.io/cross-rs/x86_64-unknown-linux-gnu:main
# Compiling libc v0.2.159
# ......
# Compiling tokio-byteorder v0.3.0
# Compiling socks5_tcp v0.1.0 (/mnt/d/socks5_tcp)
# Finished `release` profile [optimized] target(s) in 58.03s
可見,基本上分為以下幾個階段:
- 安裝目標平台的工具鏈
- 下載用於編譯的 Docker 鏡像
- 編譯程序
然後我們就得到了在 Linux 上運行的可執行文件,位於target/x86_64-unknown-linux-gnu/release/socks5_tcp
。然而,在面對複雜的項目時,可能會需要處理外部依賴;而編譯到 MacOS 或 MSVC 目標時,需要處理一些額外的配置,請看下方章節。
處理外部依賴#
為了對編譯過程做一些定制,我們需要在項目根目錄下創建一個Cross.toml
文件,內容如下:
# 此處格式為 `target.<target-triple>`,可以存在多個不同目標的配置
[target.aarch64-unknown-linux-gnu]
# pre-build 可以在編譯前執行一些命令,常用於安裝依賴
pre-build = [
"apt-get update",
"apt-get install -y libssl-dev",
]
# 也可以用 image 來指定一個Docker鏡像
image = "test-image"
# 指定一些環境變量
env.aaa = "bbb"
基本上配置方法就是如上,如果需要進一步定制,請參考官方文檔。
編譯到 MacOS#
由於許可原因,cross-rs
團隊無法為我們提供預編譯好的鏡像,也不被允許分發 Apple 的 SDK,所以我們需要自己以合法方式獲取到 SDK,進而編譯一個鏡像。下方我以aarch64-apple-darwin
為例,其他平台類似。
編譯鏡像#
我們需要克隆cross-rs
的代碼,並更新子模塊,完成配置後構建鏡像:
# Setup cross toolchains
git clone https://github.com/cross-rs/cross
cd cross
git submodule update --init --remote
cargo xtask configure-crosstool
# Build docker images
cargo build-docker-image aarch64-apple-darwin-cross --build-arg 'MACOS_SDK_URL=https://github.com/joseluisq/macosx-sdks/releases/download/12.3/MacOSX12.3.sdk.tar.xz' --tag local
# Compile our application
cross build --target aarch64-apple-darwin --release
構建對 SDK 版本要求如下:
- i686-apple-darwin: SDK <= 10.13
- x86_64-apple-darwin: SDK <= 13.0 or SDK <= 12.4
- aarch64-apple-darwin: SDK >= 10.16 and (SDK <= 13.0 or SDK <= 12.4)
配置 Cross.tomml
#
構建完畢後,就很簡單了,我們只需要在項目根目錄下創建一個Cross.toml
文件,指定對應目標使用我們的本地鏡像,內容如下:
# Reference: https://github.com/cross-rs/cross-toolchains
[target.aarch64-apple-darwin]
image = "ghcr.io/cross-rs/aarch64-apple-darwin-cross:local"
後續的編譯就和 Linux 一樣了,不再贅述。
編譯到 Windows#
MSVC 或許是 Windows 下最優的目標,然而為了方便起見,我還是選擇了 GNU 工具鏈。我們可以使用x86_64-pc-windows-gnu
或i686-pc-windows-gnu
作為目標,編譯方法和 Linux 類似:
cross build --target x86_64-pc-windows-gnu --release
這樣我們就能夠在 Linux 或 MacOS 上編譯出 Windows 下的可執行文件了,不需要配置 MSVC。如果你非常想要 MSVC 的編譯結果,請自行閱讀官方倉庫的 README 和 Issue 吧。