Rust 支持交叉编译,可以 macOS 平台编译出 Linux 或者 Windows 可运行的程序,或者在 Linux 平台编译 macOS 或者 Windows 可运行的程序。
这篇文章主要讲解 Mac 平台编译为其他平台的二进制程序。
想要实现跨平台编译并且可运行的程序,那么我们就需要静态链接,这样生成程序才不会因为动态链接库的原因运行失败。
在默认情况下,Rust 静态连接所有 Rust 代码。如果程序中使用了标准库,Rust 会连接到系统的 libc 实现。
环境
- macOS:
- OS:
macOS 12.3.1 21E258 x86_64 - rustc:
rustc 1.60.0 (7737e0b5c 2022-04-04) - rustup:
rustup 1.24.3 (ce5817a94 2021-05-31)
- OS:
- Linux:
- OS:
EndeavourOS Linux x86_64 - kernel:
5.17.1-arch1-1 - rustc:
rustc 1.60.0 (7737e0b5c 2022-04-04) - rustup:
rustup 1.24.3 (ce5817a94 2021-05-31)
- OS:
首先需要安装 Rust,使用命令 `` 。
示例准备
使用 Cargo 新建二进制项目:
| |
文件 main.rs:
| |
macOS 编译为 Linux 和 Windows 可用二进制程序
编译为 Linux 平台
要实现 Linux 平台可以运行的程序,那么需要使用 musl 来替代
glibc,musl 实现了Linux libc。
musl 在 macOS 上使用 musl-cross,musl-cross 是用来专门编译到 Linux 的工具链,下面进行安装:
| |
还需要创建 musl-gcc:
| |
添加对应的 Target,只需要执行一次就可以了:
| |
修改配置文件 ~/.cargo/config (如果没有可以新建),添加如下内容:
| |
也可在项目根目录下创建
.cargo/config文件,只对当前项目生效
编译:
| |
结果:
| |
编译为 Windows 平台
mingw-w64 是用来编译到 Windows 的工具链,使用如下命令进行安装:
| |
接下来添加 mingw-64 对应的 Target,只需要执行一次就可以了:
| |
修改配置文件 ~/.cargo/config (如果没有可以新建),设置 Linker,添加如下内容:
| |
编译:
| |
结果:
| |
在 Linux 编译为 macOS 和 Windows
编译为 macOS 平台
在 Linux 编译 macOS 平台使用 osxcross。osxcross 可以在 Linux/FreeBSD/OpenBSD 以及 Android (Termux) 交叉编译 macOS 平台的工具。
我看了下 osxcross 编译为 macOS 平台真的还是挺麻烦的,我决定不编译为 macOS 版本,何必为难自己呢,何况自己有 Mac 电脑呢 😂。
编译为 Windows 平台
mingw-w64 是用来编译到 Windows 的工具链,Arch 对应的包为 mingw-w64-gcc,接下来进行安装:
| |
接下来就容易了,和 “macOS 编译为 Linux 和 Windows” 一样了,就是添加 Target,修改配置文件,然后编译就可以了。
FAQ
x86_64-unknown-freebsd target may not be installed
自己在 Mac 平台的时候,把上述所有的操作都做了,但是还是包如下错误:
| |
那么怎么解决的呢,我发现自己之前使用 Homebrew 安装过 rust,而且还使用官方命令 curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh 再次进行安装,导致 rust 工具链对不上,只需要做如下操作就可以了:
- 先完全卸载
| |
- 重新安装:
| |
error:linking with cc failed:exit status:1
配置 ~/.cargo/config 或者在项目内 .cargo/config 文件就可以解决这个问题。
总结
介绍了在 macOS 编译为 Linux/Windows 以及 Linux 平台编译为 macOS/Windows,其实就两个三个步骤:
- 添加相应的 Target
- 安装对应的 Linker
- 修改配置文件
从 macOS 编译其他的平台,其实是比较容易的,从其他平台编译为 macOS 平台却不那么简单,最终自己放弃了。
Reference
- MUSL 支持完全静态二进制文件
- Rust on Lambda
- Cross-compiling a simple Rust web app
- How to Cross-Compile from Mac to Linux on Rust
- MUSL support for fully static binaries
- Cross-compile and link a static binary on macOS for Linux with cargo and rust
- Everything you need to know about cross compiling Rust programs
- Cross-compiling Rust from ARM to x86-64
- Cross compiling Rust from Linux to macOS
