rust交叉编译

toolchaintarget分别是, toolchain是交叉编译所需的“编译工具”, 而target则是编译到目标平台所需的"库文件"

什么是 Toolchain

toolchain 指一组Rust工具, 包括编译器(rustc), 构建工具(cargo), 文档生成工具(rustdoc)以及其他与 Rust 相关的实用程序. Toolchain用于管理和构建 Rust 代码, 并且可以包括一个特定版本的 Rust 编译器和标准库, 还包含一个默认是编译到本机平台的target. 工具链的版本可以是 "stable"(稳定版), "beta"(测试版)或 "nightly"(每日构建版), 每个版本都对应着不同的 Rust 编译器和特性. 工具链中的工具命令了, 它们通常存储在~/.cargo/bin这个目录下.

什么是 Rustc target

Rust 中的target概念主要是为了支持跨平台开发和交叉编译, 以确保 Rust 代码可以在不同的操作系统和架构上正确运行. Rustc target指的是编译和构建目标平台Rust代码时需要的组件. 不要混淆为Rust项目编译后产生的target文件夹. 它的格式表示为: <arch>-<vendor>-<os>-<abi>. 其中:

  • <arch> 表示架构(例如, x86_64 表示64位的x86架构).
  • <vendor> 表示供应商(一般为空).
  • <os> 表示操作系统(例如, linux, windows, macos 等).
  • <abi> 表示二进制接口(例如, 默认的是 "gnu", 也可以是 "musl", "msvc" 等)

例如:

  • x86_64-unknown-linux-gnu: 64位 x86 架构, Linux 操作系统, 使用 gnu.
  • x86_64-unknown-linux-musl 64位 x86 架构, Linux 操作系统, 使用 musl.
  • i686-pc-windows-msvc: 32位 x86 架构, Windows 操作系统, 使用 MSVC 编译器.

一般来说只需要rustup target add <target>命令安装某个目标平台组件即可, 但对于一些特殊平台, 可能需要手动安装相关的交叉编译工具链, 例如windows msvc或者android NDK.

常用命令:

# 列出可用的target
rustup target list
# 安装一个新的rustup target add <target>
rustup target add x86_64-unknown-linux-gnu
# 把代码编译到指定平台
cargo build --target x86_64-unknown-linux-gnu

Rust编译流程

Source code -> MIR -> LLVM IR -> 机器码 -> Target链接 -> 可执行文件或库

Linux平台为例, Rust编译器就是rustc

  • 首先会把源码编译为MIR
  • 然后交给LLVM处理, LLVM继续把MIR先编译成LLVM IR.
  • 进而编译为目标平台的机器码(此时还不是执行文件, 只是一堆机器码)
  • 往后就是target发挥作用了, target调用msvcgnu来完成链接步骤, 主要是链接目标平台库文件并生成可执行文件.

这里整个编译过程几乎都是由rustc完成的, 因为它包含了llvm和调用target的代码, 跟目标平台相关的工作则是由msvcgnu来完成. msvcgnuc/c++的编译工具链, 编译后的最终产物就是可执行文件或库, rustc在编译后期用到了它们提供的功能.

交叉编译

Ubuntu默认的targetgnu的, 依赖glibc, 但是其他Linux系统未必是glibc是基础库, 但是可以用同一套toolchain(编译器之类的), 因此只需要添加target即可.

而交叉编译到Windows, 则Linux的编译器是没有这个能力的, 因此需要添加Windows平台的toolchain(有部分toolchain官方没有实现还得添加第三方的toolchain), 然后再添加target. 注意, 如果Windows选择的是msvc而非gnu, 那么哪怕是最简单的hello world也必须要安装visual studio(主要是需要它携带的toolchain[linker等])

References