跳到主要内容

对Rust 代码交叉编译多个平台的可执行程序

概览

这篇文章介绍了如何对你的Rust进行交叉编译,以下是我操作时用到的环境和代码:

  • 示例代码:tool-clip-json-sort,很简单的一个rust项目,对剪切版里面的json内容进行排序格式化,然后重新放入剪切版。
  • 服务器环境centos7,已经安装docker

交叉编译生成windows可执行程序

提前把准备好你需要交叉编译的代码

构建镜像

创建Dockerfile,然后输入

FROM rust:latest

RUN apt update && apt upgrade -y
RUN apt install -y g++-mingw-w64-x86-64

RUN rustup target add x86_64-pc-windows-gnu
RUN rustup toolchain install stable-x86_64-pc-windows-gnu

WORKDIR /app

CMD ["cargo", "build", "--release","--target", "x86_64-pc-windows-gnu"]

这个Dockerfile使用了Rust的最新版本作为基础映像。它然后更新了操作系统并安装了g++-mingw-w64-x86-64软件包。这个软件包是一个MinGW交叉编译工具链,可以在Linux主机上构建Windows二进制文件。

接下来,Dockerfile通过运行rustup命令添加了一个名为x86_64-pc-windows-gnu的Rust目标,这是一个Windows 64位目标。最后,Dockerfile将工作目录设置为/app并定义了一个默认命令,该命令使用cargo构建Windows 64位目标的可执行文件。在这种情况下,cargo build使用--target选项指定了目标,并使用--release选项来生成优化的可执行文件。

使用此Dockerfile构建的Docker映像将提供一个可用于在Linux主机上构建Windows 64位可执行文件的环境。

进行构建

docker build . -t rust_cross_compile/windows

构建完成之后可以通过docker images可看到刚刚构建的镜像

对项目进行交叉编译

进入你的项目根目录

然后执行

docker run --rm -v "$(pwd)":/app rust_cross_compile/windows

此时docker会根据你刚刚构建的镜像运行一个容器,这个容器会挂载当前目录到容器中的工作目录,并通过cross对你的rust代码进行交叉编译,生成windows的可执行程序。

当跑完之后,你可以在当前目录下的release目录下找到生成的.exe文件

交叉编译生成intel-MacOS可执行程序

经过上面那个步骤你会发现其实很简单,那么MacOS其实也查不到,构建镜像

Dockerfile

FROM rust:latest

RUN rustup target add x86_64-apple-darwin
RUN rustup toolchain install stable-x86_64-apple-darwin

WORKDIR /app

CMD ["cargo", "build","--release", "--target", "x86_64-apple-darwin"]

构建镜像

docker build . -t rust_cross_compile/intel-macos

对项目进行交叉编译

docker run --rm -v "$(pwd)":/app rust_cross_compile/intel-macos

其他平台

这里再附加一下其他的dockerfile

armv7

FROM rust:latest

RUN apt update && apt upgrade -y
RUN apt install -y g++-arm-linux-gnueabihf libc6-dev-armhf-cross

RUN rustup target add armv7-unknown-linux-gnueabihf
RUN rustup toolchain install stable-armv7-unknown-linux-gnueabihf

WORKDIR /app

ENV CARGO_TARGET_ARMV7_UNKNOWN_LINUX_GNUEABIHF_LINKER=arm-linux-gnueabihf-gcc CC_armv7_unknown_Linux_gnueabihf=arm-linux-gnueabihf-gcc CXX_armv7_unknown_linux_gnueabihf=arm-linux-gnueabihf-g++

CMD ["cargo", "build","--release", "--target", "armv7-unknown-linux-gnueabihf"]

aarch64

FROM rust:latest

RUN apt update && apt upgrade -y
RUN apt install -y g++-aarch64-linux-gnu libc6-dev-arm64-cross

RUN rustup target add aarch64-unknown-linux-gnu
RUN rustup toolchain install stable-aarch64-unknown-linux-gnu

WORKDIR /app

ENV CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER=aarch64-linux-gnu-gcc CC_aarch64_unknown_linux_gnu=aarch64-linux-gnu-gcc CXX_aarch64_unknown_linux_gnu=aarch64-linux-gnu-g++

CMD ["cargo", "build", "--release","--target", "aarch64-unknown-linux-gnu"]

那么你可能会说Linux 的是不是也是这样?因为本身就是linux系统,那为啥还要这么折腾,直接cargo build —-release