cross-rs: 无配置可跨平台编译与测试

虽然说 Rust 是跨平台的,原生也是可以通过指定 target 的方式来进行跨平台编译,但实际使用过程中总是常常因为一些系统配置或者应用的缺失导致编译失败。

因此合理的一个想法就是,通过 docker 这种标准化的隔离环境进行编译。rust 中就有这样的应用:cross,根据指定的 target,开启合适的容器来进行编译。这样就不用再为配置环境或者安装相应的工具链而费心。

使用起来非常简单,只需要前置安装一个 docker 或者 podman,使得系统可支持容器就行。在 macOS 上通过 OrbStack 使用 docker 的体验很好,安装完命令行直接支持。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# 首先安装 cross
cargo install cross --git https://github.com/cross-rs/cross

# 启动 docker

# 指定 target 进行编译
cross build --target x86_64-unknown-linux-musl
cross build --target x86_64-unknown-linux-musl --release

# 指定 target 进行测试
cross test --target mips64-unknown-linux-gnuabi64

不过编译速度稍慢,可能是因为套了层 docker 的原因,比直接编译慢多了,甚至感觉还不如以前在 Windows 上用 WSL 来编译 Linux 版本。

另外这样用 docker 来编译的话,一些依赖 crate 的编译结果也没得缓存,每次都需要重新把所有 crate 都编译一次,有点折磨。

不过看了下 issue,说是实际其实已经支持 incremental build 的。 但是使用 cargo 和 cross 来编译,都只会使用 target/debug|release 目录下的内容作为 cache,而不同 target 之间是不能够复用的。如果在 cross 为指定 target 编译一次后,target/release 目录下的内容都会变成只针对指定 target 有效,这时使用 cargo 本地编译就得全部重新编译(包括全部依赖的 crate 😭)。而这样 cargo 编译后,又重写了 target/release 的内容,后续使用 cross 跨平台编译又得重新全部编译一次。虽然最终 cross 打出来的内容会放在 target/{target-host}/release 下面,但是似乎使用的是 target/release,导致这个能否增量编译的设置就很迷,几乎等于没有。