Rust交叉编译

Rust交叉编译

实际上 Cargo 已经准备了很多目标平台,我们可以通过 rustup target list 命令来查看可以交叉编译的平台。

x86_64-apple-darwin (installed)
x86_64-apple-ios
x86_64-fortanix-unknown-sgx
x86_64-linux-android
x86_64-pc-solaris
x86_64-pc-windows-gnu (installed)
x86_64-pc-windows-gnullvm
x86_64-pc-windows-msvc
x86_64-unknown-freebsd
x86_64-unknown-fuchsia
x86_64-unknown-illumos
x86_64-unknown-linux-gnu (installed)
x86_64-unknown-linux-gnux32
x86_64-unknown-linux-musl
x86_64-unknown-linux-ohos
x86_64-unknown-netbsd
x86_64-unknown-none

对于 Windows 和 Linux 而言,大多数情况下,通过rustup target add xxx安装目标平台的支持之后,就可以使用
cargo build -r --target xxx 来编译出对应平台的可执行文件。但是在编译 MacOS 的时候遇到了问题,它需要 macOS SDK,对于普通场景而言,你只需要在 MacOS 上编译就行了,但是对于自动化的构建流程而言,这将是极大的麻烦。但是 zig 有一个强大的工具链,支持交叉编译和多版本的 glibc(Rust 不支持低版本的 glibc)。我们借助 zig 的编译链来增强 rust 的交叉编译能力。

cargo-zigbuild

cargo-zigbuild 项目使用 zig 作为链接器来编译 rust 项目,极大的方便我们交叉编译 rust 项目。

安装

可以使用 cargo install 来安装

cargo install --locked cargo-zigbuild

也可以使用 pip 来安装

pip install cargo-zigbuild

无论是那种方式,都会自动安装 ziglang

除此之外,该项目还提供了一个 Docker 镜像,除了 cargo-zigbuild 和 Rust 之外,它还预装了 macOS SDK,来帮助我们针对 MacOS 进行编译。例如,针对 x86_64 架构的 MacOS 进行构建。

在 rust 项目目录下,执行下面的命令,即可针对 x86_64 架构的 MacOS 进行构建

docker run --rm -it -v $(pwd):/io -w /io messense/cargo-zigbuild cargo zigbuild --release --target x86_64-apple-darwin

当然了,你也可以分步操作,首先进入容器,然后在进行项目构建。在我们这里,可能需要对镜像做一个改造,因为镜像里的 rust 仓库是 crates.io,我们需要换源。也可以将准备好的配置文件挂载到容器上去。例如:

docker run --rm -it -v $(pwd):/io -v $(pwd)/config.toml:/usr/local/cargo/config.toml -w /io messense/cargo-zigbuild cargo zigbuild --release --target x86_64-apple-darwin

这样就可以将当前目录下的 config.toml 挂载到容器的 /usr/local/cargo/config.toml, 这样就可以使用国内的镜像源了,能够极大的提高下载速度。

使用

前面在 docker 镜像这里提到了如何使用,其实非常简单,只需要下面一行命令即可:

cargo zigbuild --target aarch64-unknown-linux-gnu --release

这样就完成了交叉编译到目标平台。

指定 glibc 版本

cargo zigbuild 支持在选项中传递 glibc 版本,例如, 要针对 glibc 2.17 进行编译,目标是:aarch64-unknown-linux-gnu

此时,你可以在目标后面加上 glibc 的版本:

cargo zigbuild --target aarch64-unknown-linux-gnu.2.17

macOS universal2 目标

cargo zigbuild 支持在 Rust 1.64.0 及更高版本上构建 macOS universal2 二进制文件/库的特殊目标

例如:

rustup target add x86_64-apple-darwin
rustup target add aarch64-apple-darwin

cargo zigbuild --target universal2-apple-darwin

对于编译完成的 MacOS 平台的二进制文件,你会发现有 strip 执行失败的警告。尝试手动使用 strip 命令去除符号和调试信息,也会失败。

这时候,我们需要安装 cargo-binutils,它可以帮助我们方便地调用 Rust 内置的 LLVM binutils

cargo install cargo-binutils
ustup component add llvm-tools-preview

安装完成 LLVM 套件之后,我们会有一个 rust-objcopy 的命令可用,可以通过 rust-objcopy 将可执行程序中的多余信息给剥离。

rust-objcopy xxx --strip-all -O binary xxx-darwin-universal2
相关推荐
SoraLuna2 小时前
「Mac畅玩鸿蒙与硬件47」UI互动应用篇24 - 虚拟音乐控制台
开发语言·macos·ui·华为·harmonyos
阿7_QuQ3 小时前
怎么在Windows上远程控制Mac电脑?
macos
小路恢弘8 小时前
使用Mac自带共享实现远程操作
macos
阿髙16 小时前
macos 隐藏、加密磁盘、文件
macos
minos.cpp19 小时前
Mac上Stable Diffusion的环境搭建(还算比较简单)
macos·ai作画·stable diffusion·aigc
SomeB1oody1 天前
【Rust自学】4.1. 所有权:栈内存 vs. 堆内存
开发语言·后端·rust
追光天使1 天前
Mac/Linux 快速部署TiDB
linux·macos·tidb
wzkttt1 天前
Mac gfortran编译fortran出错
macos·gfortran
刘小哈哈哈1 天前
iOS 多个输入框弹出键盘处理
macos·ios·cocoa
草明2 天前
macOS 显示或不显示隐藏文件
macos