Featured image of post Rust 交叉编译 macOS 为 Linux 和 Windows

Rust 交叉编译 macOS 为 Linux 和 Windows

> Rust 支持交叉编译,可以 macOS 平台编译出 Linux 或者 Windows 可运行的程序,或者在 Linux 平台编译 macOS 或者 Windows 可运行的程序。

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)
  • 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)

首先需要安装 Rust,使用命令 `` 。

示例准备

使用 Cargo 新建二进制项目:

1
cargo new --bin hello

文件 main.rs

1
2
3
fn main() {
  println!("Hello World!\n");
}

macOS 编译为 Linux 和 Windows 可用二进制程序

编译为 Linux 平台

要实现 Linux 平台可以运行的程序,那么需要使用 musl 来替代 glibcmusl 实现了 Linux libc

musl 在 macOS 上使用 musl-cross,musl-cross 是用来专门编译到 Linux 的工具链,下面进行安装:

1
brew install FiloSottile/musl-cross/musl-cross    

还需要创建 musl-gcc

1
ln -s /usr/local/bin/x86_64-linux-musl-gcc /usr/local/bin/musl-gcc

添加对应的 Target,只需要执行一次就可以了:

1
rustup target add x86_64-unknown-linux-musl

修改配置文件 ~/.cargo/config (如果没有可以新建),添加如下内容:

1
2
[target.x86_64-unknown-linux-musl]
linker = "x86_64-linux-musl-gcc"

也可在项目根目录下创建 .cargo/config 文件,只对当前项目生效

编译:

1
2
# 使用
cargo build --release --target x86_64-unknown-linux-musl

结果:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
$ tree -L 2 target/x86_64-unknown-linux-musl 
target/x86_64-unknown-linux-musl
├── CACHEDIR.TAG
└── debug
    ├── build
    ├── deps
    ├── examples
    ├── hello
    ├── hello.d
    └── incremental

5 directories, 3 files
$ file target/x86_64-unknown-linux-musl/debug/hello
target/x86_64-unknown-linux-musl/debug/hello: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), static-pie linked, with debug_info, not stripped

编译为 Windows 平台

mingw-w64 是用来编译到 Windows 的工具链,使用如下命令进行安装:

1
brew install mingw-w64  

接下来添加 mingw-64 对应的 Target,只需要执行一次就可以了:

1
$ rustup target add x86_64-pc-windows-gnu

修改配置文件 ~/.cargo/config (如果没有可以新建),设置 Linker,添加如下内容:

1
2
3
[target.x86_64-pc-windows-gnu]
linker = "x86_64-w64-mingw32-gcc"
ar = "x86_64-w64-mingw32-gcc-ar"

编译:

1
2
# 使用
$ cargo build --release --target x86_64-unknown-linux-musl

结果:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
$ tree -L 2 target/x86_64-pc-windows-gnu
target/x86_64-pc-windows-gnu
├── CACHEDIR.TAG
└── debug
    ├── build
    ├── deps
    ├── examples
    ├── hello.d
    ├── hello.exe
    └── incremental

5 directories, 3 files
$ file target/x86_64-pc-windows-gnu/debug/hello.exe
target/x86_64-pc-windows-gnu/debug/hello.exe: PE32+ executable (console) x86-64, for MS Windows

在 Linux 编译为 macOS 和 Windows

编译为 macOS 平台

在 Linux 编译 macOS 平台使用 osxcrossosxcross 可以在 Linux/FreeBSD/OpenBSD 以及 Android (Termux) 交叉编译 macOS 平台的工具。

我看了下 osxcross 编译为 macOS 平台真的还是挺麻烦的,我决定不编译为 macOS 版本,何必为难自己呢,何况自己有 Mac 电脑呢 😂。

编译为 Windows 平台

mingw-w64 是用来编译到 Windows 的工具链,Arch 对应的包为 mingw-w64-gcc,接下来进行安装:

1
sudo pacman -S mingw-w64-gcc

接下来就容易了,和 “macOS 编译为 Linux 和 Windows” 一样了,就是添加 Target,修改配置文件,然后编译就可以了。

FAQ

x86_64-unknown-freebsd target may not be installed

自己在 Mac 平台的时候,把上述所有的操作都做了,但是还是包如下错误:

1
2
3
4
5
6
error[E0463]: can't find crate for `std`
  |
  = note: the `x86_64-unknown-freebsd` target may not be installed
  = help: consider downloading the target with `rustup target add x86_64-unknown-freebsd`

error: requires `sized` lang_item

那么怎么解决的呢,我发现自己之前使用 Homebrew 安装过 rust,而且还使用官方命令 curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh 再次进行安装,导致 rust 工具链对不上,只需要做如下操作就可以了:

  1. 先完全卸载
1
2
$ brew uninstall rust
$ rustup self uninstall
  1. 重新安装:
1
$ curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

error:linking with cc failed:exit status:1

配置 ~/.cargo/config 或者在项目内 .cargo/config 文件就可以解决这个问题。

总结

介绍了在 macOS 编译为 Linux/Windows 以及 Linux 平台编译为 macOS/Windows,其实就两个三个步骤:

  1. 添加相应的 Target
  2. 安装对应的 Linker
  3. 修改配置文件

从 macOS 编译其他的平台,其实是比较容易的,从其他平台编译为 macOS 平台却不那么简单,最终自己放弃了。

Reference

Licensed under CC BY-NC-SA 4.0
最后更新于 May 15, 2022 06:23 UTC
comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计