Rust交叉编译Mac编译Linux平台

full Rust cross compiler

关于交叉编译

绝大部分的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环境下编译也有问题,每次都得重新拉取资源,其次是容易卡,其它都还好。

分享

TITLE: Rust交叉编译Mac编译Linux平台

LINK: https://www.qttc.net/529-rust-cross-compile-mac-to-linux.html

NOTE: 原创内容,转载请注明出自琼台博客