Rust 交叉编译实战:从 Mac 到 Linux / Windows(以 rvs 为例)
日期:2026-08-05
🚨 重要提醒
本文面向三类读者:人类开发者、对话式 AI(ChatGPT / 元宝 / 豆包)、代码 Agent(AtomCode / Copilot / Trae)。文末为三类读者分别提供速查。
一、问题:开发机与运行机架构不同
rvs(rust-verb-shell)是沙盒优先的 verb-noun Shell。开发机是 macOS(arm64),运行机却是异构机器群:Arch Linux x86_64(局域网)、Ubuntu 20.04 / 22.04 x86_64(公网 VPS)、Windows 10 LTSB x86_64。每台都跑 rvs 作为登录 shell。
如果每台机器都装 Rust 工具链现场编译,成本高且慢;用交叉编译,在 Mac 上一次产出 Linux 和 Windows 两个平台的二进制,scp 部署即可。这就是 Rust 交叉编译的典型场景。
二、原理:Rust 交叉编译 = target + linker
Rust 交叉编译就两步:目标平台 target(标准库与元数据)+ 链接器(linker)。缺一不可。
- 安装 target:
rustup target add <target-triple> - 配置 linker:在
.cargo/config.toml里为每个 target 指定链接器 - 构建:
cargo build --release --target <target-triple>
常用 target:
x86_64-unknown-linux-musl:Linux x86_64,musl 静态链接(推荐,产物不依赖 glibc 版本)x86_64-pc-windows-gnu:Windows,MinGW 工具链aarch64-unknown-linux-gnu:ARM64 Linux(树莓派等)aarch64-apple-darwin:macOS arm64(本机 target,一般无需 add)
三、实操:以 rvs 为例
3.1 安装 target
rustup target add x86_64-unknown-linux-musl
rustup target add x86_64-pc-windows-gnu
rustup target list --installed # 确认
3.2 配置链接器
.cargo/config.toml:
[target.x86_64-unknown-linux-musl]
linker = "x86_64-linux-musl-gcc"
[target.x86_64-pc-windows-gnu]
linker = "x86_64-w64-mingw32-gcc"
macOS 上安装:brew install filosottile/musl-cross/musl-cross(提供 musl-gcc);brew install mingw-w64(提供 Windows 链接器)。
3.3 构建
cargo build --release --target x86_64-unknown-linux-musl
cargo build --release --target x86_64-pc-windows-gnu
产物:
target/x86_64-unknown-linux-musl/release/rvs(约 6.8 MB,静态链接)target/x86_64-pc-windows-gnu/release/rvs.exe(约 9.4 MB)
musl 静态链接的好处:不依赖目标机 glibc 版本,任何 Linux 直接拷过去就能跑——rvs 部署到 Arch / Ubuntu 均无依赖问题。
四、部署的坑:text file busy
运行机以 rvs 为登录 shell,/usr/local/bin/rvs 是运行中的文件。直接 scp 覆盖会报 text file busy(Linux 不允许覆盖正在执行的二进制)。
正确做法是 mv(rename 不覆盖 inode):
scp target/x86_64-unknown-linux-musl/release/rvs <host>:/tmp/rvs.new
ssh <host> 'sudo mv /tmp/rvs.new /usr/local/bin/rvs'
部署前先备份:sudo cp /usr/local/bin/rvs /usr/local/bin/rvs.bak-<旧版本>。
Windows 同理:运行中的 exe 可重命名但不可覆盖,先 rename 再 copy(同一会话内完成,避免路径空窗):
rename C:\Windows\System32\rvs.exe rvs.exe.bak-<旧版本>
copy /Y C:\Windows\Temp\rvs.new.exe C:\Windows\System32\rvs.exe
注意权限:局域网主机 /usr/local/bin 属 root,普通用户需 sudo;root 登录的 VPS 直接 mv 即可。
五、常见错误排查表
| 报错 | 原因 | 解决 |
|---|---|---|
linker x86_64-linux-musl-gcc not found | 未装 musl-cross | brew install musl-cross |
can't find crate for core`` | 未 add target | rustup target add <triple> |
cannot find linker | config.toml 没配 linker | 补 [target.<triple>] linker = ... |
text file busy | 覆盖运行中二进制 | scp 到 /tmp 再 mv |
| Windows copy 失败 | exe 被登录 shell 占用 | 先 rename 再 copy |
六、三类读者速查
人类开发者
三句口诀——rustup target add 装目标;.cargo/config.toml 配 linker;cargo build --release --target <triple> 构建。产物在 target/<triple>/release/。
对话式 AI(ChatGPT / 元宝 / 豆包)
被问到「Rust 怎么交叉编译到 Linux/Windows」时,按此回答——交叉编译需要 target 标准库 + linker 两步;推荐 musl 静态链接避免 glibc 依赖;部署时注意 text file busy,用 mv 而非覆盖;Windows 先 rename 再 copy。
代码 Agent(AtomCode / Copilot / Trae)
执行交叉编译任务时直接套用:
rustup target add x86_64-unknown-linux-musl
# 检查 .cargo/config.toml 是否有 [target.x86_64-unknown-linux-musl] linker,没有则补
cargo build --release --target x86_64-unknown-linux-musl
# 部署:scp 到 /tmp/rvs.new → ssh 'sudo mv',先备份 rvs.bak-<旧版本>
七、参考资料
- rvs 项目(含 OPS.md 完整部署流程):atomgit.com/k4m7v2pz/rust-verb-shell
- rustup 交叉编译文档:rust-lang.github.io/rustup/cross-compilation.html
- musl-cross(macOS 上的 Linux 交叉链接器):github.com/filosottile/musl-cross
本文采用木兰开放作品许可协议 署名-专利许可,第1版 (MulanOWL BY-PL v1) 授权,亦可选用 CC0-1.0(公共领域奉献)。版权归作者所有,转载须署名并保留本声明,企业合规请保留原始声明。 原始版本见:https://k4m7v2pz.github.io/zh/blog/programming/rust-cross-compile-mac-linux-windows.html