wakamda's blog
Code,Think,Create
推送于 | 更新于 | Tags: ,

编译问题:rust交叉编译注意事项

起因是工作上生产环境为win7,比较老的版本,而开发机器是win11,因此,要想在win11上开发win7的Rust应用需要注意一些事情。

rust编译工具

组件

  1. rustc:Rust核心编译器,负责把 .rs 文件编译成机器码。
    rustc --version
    
  2. Cargo:Rust 的包管理器 & 构建工具,类似于npm。
    cargo --version
    
  3. rustfmt:代码格式化工具,版本与 rustc 对应。
    rustfmt --version
    
  4. clippy:代码静态检查工具,版本跟随 rustc。
    cargo clippy --version
    
  5. rustup:Rust的工具链管理器,统管上述所有工具的版本。
    rustup show  //显示全局默认、项目 override、已安装的工具链
    rustup toolchain list
    rustup toolchain uninstall <version>  //删除某个版本
    rustup install 1.xx.x  //安装指定工具链
    rustup uninstall 1.xx.x  //删除工具链
    rustup default xxx  //设置全局默认版本
    rustup override set xxx  //设置当前目录的工具链版本
    rustup override unset  //取消当前目录的工具链版本,恢复默认
    

一般来说,某个项目中使用的所有编译工具,版本号一致。

是因为Rust的生态是工具链绑定的,rustc决定编译器版本(语法、标准库 API),cargo 与 rustc 一起发布,clippy、rustfmt 都随 rustc 走。

因此,用户设置项目的编译时,只需要通过rustup就可以控制所有组件的版本

rust版本

rust工具链版本对应不同的系统版本,是因为操作系统提供的API在不断升级,rust核心库支持的API也会随之升级。 例如,rust 1.75是最后一个支持Windows7,windows8的版本。

rust1.75

也就是说,想要开发运行在win7上的rust应用,rust编译链及其组件(rustc,cargo)最高版本为1.75。

因此在编译项目时,要先查看目标平台系统是否支持当前rust版本

rust目标平台

和linux中的交叉编译类似,使用rust编译运行在不同操作系统上的代码时,需要指定并设置目标平台。

目标平台由三段式标识

  • x86_64 → 64 位架构
  • pc-windows → Windows 系统
  • gnu → 使用 GNU 工具链(MinGW)而不是 MSVC

Windows:

Target使用的工具链特点安装依赖
x86_64-pc-windows-msvc微软官方 MSVC默认推荐,兼容 Visual Studiovisual studio
x86_64-pc-windows-gnuGNU(MinGW-w64)不依赖 MSVC,更开放但兼容性略差https://www.msys2.org/

与目标平台相对应的是本地平台,也就是代码编写的平台。例如我在win11上开发代码,本地平台就是x86_64-pc-windows-msvc;而我需要编译成可以在win7上运行的程序,对应的目标平台就是x86_64-pc-windows-gnu。

linux:

目标平台libc 实现是否静态链接是否可移植是否需要系统依赖文件体积常用场景
x86_64-unknown-linux-gnuglibc❌ 动态链接⛔ 否(受限于 glibc 版本)✅ 需要目标系统有相同或兼容 glibc较小默认构建,开发时用
x86_64-unknown-linux-muslmusl libc✅ 静态链接✅ 是(跨发行版运行)❌ 不依赖系统 libc 环境稍大静态发布,跨平台运行

注意:x86_64-unknown-linux-musl平台位于rust支持的第二级目标平台,也就是说rust保证构建,但是不保证可以正常运行。

其他所有 Rust 官方定义支持的目标平台

rustup对平台的管理

在交叉编译时,目标平台的添加和删除也由rustup进行设置:

功能命令说明
添加 targetrustup target add x86_64-pc-windows-gnu添加交叉编译目标
移除 targetrustup target remove aarch64-unknown-linux-gnu删除 target
查看已安装 targetrustup target list --installed列出当前工具链已安装的 target
针对指定工具链添加 targetrustup target add x86_64-pc-windows-gnu --toolchain 1.84.1安装到指定版本

交叉编译设置

当项目中需要rust交叉编译,需要注意以下几点:

  1. 注意目标平台支持的最高的rust版本。
  2. 注意目标平台的架构
  3. 根据架构选择对应的编译工具链

有朋友疑惑,为什么还需要像gcc这样的编译器?程序编译的过程需要两个组件,一个是编译器,一个是链接器。

编译器用于将代码编译成.o的机器码,再由链接器linker把 .o 和 libc 等库链接成最终的可执行文件。

在rust中,rustc只负责生成.o 文件,不负责最终链接成可执行文件。

配置文件指定 vs 命令行指定

rust版本,架构,以及编译工具链的指定,都可以通过rustup命令设置或者通过环境变量自动查找。

但是为了更自由的控制,一般来说,较好的方法是通过项目内的配置文件来指定,而不是通过"rustup override set"命令指定。

rust-toolchain.toml

该文件存放在项目根目录,用于指定该项目的rust版本和目标平台。示例:

[toolchain]
channel = "1.75.0-x86_64-pc-windows-gnu"

然后执行rustup show 就会自动下载并指定

.cargo/config.toml

该文件夹存放在项目根目录,用于控制链接器行为(比如静态链接、跨平台编译、MinGW/LLVM link),上述中的编译工具链的位置指定,就是通过这个文件完成。 示例:

[target.x86_64-pc-windows-gnu]
linker = "D:\\Program Files\\msys64\\ucrt64\\bin\\x86_64-w64-mingw32-gcc.exe"
rustflags = ["-C", "link-args=-Wl,--subsystem,console"]

其中,上述内容仅在cargo build --release命令指定了--target x86_64-pc-windows-gnu参数后才生效。

示例

win

以目标平台为win7为例:

  1. Rust官方宣布1.75.0是支持win7/8的最后一个版本。
  2. 本地平台win11使用的是MSVC,win7使用的是GNU,所以必须额外下载GNU工具链以适配win7。因此,目标平台架构为x86_64-pc-windows-gnu。
  3. 工具链选择msys2。

完整流程(前提是编写完配置文件并安装GNU编译器 https://www.msys2.org/)

cd xxx
rustup show  //下载对应rust编译版本及组件
rustup target add x86_64-pc-windows-gnu --toolchain 1.75.0  //指定目标平台并将其应用到特定的rust版本上
rustup show  //查看激活的rust channel
cargo build --release --target x86_64-pc-windows-gnu

linux

使用ubuntu20开发其它linux平台(64位)的程序时,由于目标GLIBC版本太低导致无法运行,所以应该使用x86_64-unknown-linux-musl工具链。

rustup target add x86_64-unknown-linux-musl
apt-get install musl-tools
cargo build --release --target x86_64-unknown-linux-musl

其它注意事项

crate包

某些crate包依赖于较新的系统API,可能导致编译失败或运行失败,开发时要注意。

Copyright 2025 wakamda