【Rust】使用Cross进行跨平台编译
Rust
的编译速度和跨平台编译相比 Go
语言就要难用很多,但这也是语言特点,当你从中受益时,必然要付出一些代价,本文主要介绍如何实现跨平台编译,使用 cross
这个工具。
我的工作台是 Mac M2
,想编译出 Linux
和 Windows
的可执行文件,使用的代码很简单,就是 Hello World
示例程序,这个不是重点。
使用 cross
首先当然是安装,按照官方的描述,可以使用下面的命令:
1 | cargo install cross --git https://github.com/cross-rs/cross |
然后是安装 docker
或者 podman
,本文以 docker
为例,讲述使用过程中遇到的问题及其解决方案。cross
的使用很简单,例如,如果我要编译 target
为 aarch64-unknown-linux-gnu
,执行:
1 | cross build --target aarch64-unknown-linux-gnu |
ghcr.io
镜像加速
cross
的工作原理是创建一个容器来构建我们的目标平台软件,但是它的镜像不是在 Dockerhub
,所以说传统的镜像加速方法不能对它起作用,另外还有下面这些镜像仓库都不可以:
gcr.io、k8s.gcr.io
:谷歌镜像仓库;quay.io
:Red Hat
镜像仓库;ghcr.io
:GitHub
镜像仓库;
例如,我要编译 target
为 aarch64-unknown-linux-gnu
以及 x86_64-pc-windows-gnu
,就需要下载这两个镜像:
ghcr.io/cross-rs/x86_64-pc-windows-gnu:edge
;ghcr.io/cross-rs/aarch64-unknown-linux-gnu:main
所有可用的 target
可以在这里找到。
加速这些镜像的方法就是我们把他下载下来然后传到 Doclerhub
,然后我们通过国内的公共镜像加速服务器就可以快速下载。当然自己搞这些太麻烦了,已经有大神做好了自动化,只需要在这里创建个issue
,就可自动帮我们完成,例如,这是我创建的两个:https://github.com/togettoyou/hub-mirror/issues
,执行完成之后,会在 Dockerhub
创建一个新的 Repo
,例如:
然后在 Cargo.toml
配置为我们新创建的镜像,例如:
1 | ... |
sh: 1: cargo: not found
当我将镜像好不容易拉到本地之后,以为可以顺利的编出我想要的软件时,没想到又遇到了错误:
1 | ~/WORKDIR/rust/examples100 ⌚ 21:23:17 |
在一番查找之后,在 Github
中找到了解决方案:
其实这个问题应该与我将 docker
装在虚拟中有关,但是这个解决方案可以从本质上解决问题,镜像中没有安装 rust
工具链。所以我又构建了新的镜像:
1 | FROM togettoyou/ghcr.io.cross-rs.aarch64-unknown-linux-gnu:main |
构建命令为:
1 | docker build -t gamelife1314/aarch64-unknown-linux-gnu . |
然后又重新更新 Cargo.toml
为我新建的镜像:
1 | ... |
再去执行编译命令,终于成功了:
x86_64-pc-windows-gnu
以同样的方式,我又编译出了 windows
上的可执行文件,下面是本地自建镜像的 Dockerfile
内容:
1 | FROM togettoyou/ghcr.io.cross-rs.x86_64-pc-windows-gnu:edge |
如果自定义了 Dockerfile
文件名,需要使用 -f
指定,构建镜像的命令为:
1 | docker build -t gamelife1314/x86_64-pc-windows-gnu -f Dockerfile.x86_64-pc-windows-gnu . |
Cargo.toml
配置使用自定义镜像:
1 | ... |
然后使用 cross
进行编译:
自建镜像
本文中涉及的 target
为 aarch64-unknown-linux-gnu
和 x86_64-pc-windows-gnu
的自建镜像已经上传到 Dockerhub
,可以直接使用。