Rust交叉编译Mac编译Linux平台

关于交叉编译

绝大部分的Rust程序员都会有跟我我一样的需求,写代码用的是 Windows 或者 Mac ,部署平台是 Linux ,这种情况下就需要使用 Cross-Compiler 交叉编译,意思是可以在当前平台 Host 下编译出目标平台 target 的可执行文件,尤其是做 ARM 平台开发的同学对这个更为熟悉。

Rust交叉编译在Github上有一个文档Rust核心员工 Jorge Aparicio 提供的一份文档 https://github.com/japaric/rust-cross ,推荐大家仔细的读一读。

对我而言,我的要求比较简单,都是 X86_64 架构,从 Mac 上编译出 unknow-linux 就好

musl工具链

musl实现了 Linux libc ,质量可靠,适配所有Linux环境,使用静态连接替换动态链接,这样就能打出一个完整的二进制文件,可以丢到任何Linux环境里运行。

当然,关于静态链接与动态链接各有优缺点,这里不细说。

安装一下

rustup target add x86_64-unknown-linux-musl

main.rs

fn main() {
  println!("Hello, world!\r\nwww.qttc.net\r\n");
}

然后这么编译

cargo build --release --target=x86_64-unknown-linux-musl

把结果丢到Linux下执行,没问题

$ ./cross_compile_test 
Hello, world!
www.qttc.net

常见问题

要是提示 /bin/sh: musl-gcc: command not found ,解决方法是安装 musl-cross

brew install filosottile/musl-cross/musl-cross

配置config

$ cat .cargo/config
...
[target.x86_64-unknown-linux-musl]
linker = "x86_64-linux-musl-gcc"
...

要是你的程序依赖原生库,需要设置一个环境变量 CC_x86_64_unknown_linux_musl=x86_64-linux-musl-gcc ,所以完整的编译命令如下

CC_x86_64_unknown_linux_musl="x86_64-linux-musl-gcc" cargo build --release --target=x86_64-unknown-linux-musl

要是你的程序使用了OpenSSL类库,这是一个麻烦的事情,目前普遍做法是在 Cargo.toml 文件中添加依赖

Cargo.toml

[dependencies]
openssl = { version = "0.10", features = ["vendored"] }

Docker编译

我更愿意推荐使用这种方式,因为使用第一种方式的话,需要安装一些工具链,还得看程序实际依赖的各种类库而做各种调整。其次是部署的时候也可以选择使用Docker部署,这样一来就几乎没有交叉编译的需求了。

Rust官方提供了Docker镜像在 hub.docker.com 上,根据官方的文档,可以使用以下命令编译出Linux平台的可执行文件

docker run --rm --user "$(id -u)":"$(id -g)" -v "$PWD":/usr/src/myapp -w /usr/src/myapp rust:1.43 cargo build --release

Docker环境下编译也有问题,每次都得重新拉取资源,其次是容易卡,其它都还好。

我来评几句
登录后评论

已发表评论数()

相关站点

热门文章