bigywater.tech
Rust · 2

rustc、Cargo 与 Rustup 的关系

rustc、Cargo、Rustup 常被一起提到,但它们是三个东西。这台机器碰巧只用 Homebrew 装了 rustc 和 cargo、没有 rustup,正好可以把前两者的边界量清楚:rustc 带着什么、cargo 到底怎么调用 rustc、缺了 rustup 会少什么。rustup 本身没有装,所以关于它的部分我只写「没有」的证据。

3 个
角色:rustc(编译器)、cargo(构建与依赖管理)、rustup(工具链管理,本机没装)
330
rustc 认识的目标三元组数(只装了宿主平台的标准库)
RUSTC
cargo 用这个环境变量找编译器

本机有什么

实测 · 本机执行输出
  $ command -v rustc; command -v cargo; command -v rustup || echo "rustup: 本机没有"
    /opt/homebrew/bin/rustc
    /opt/homebrew/bin/cargo
    rustup: 本机没有 
  $ rustc --version
    rustc 1.98.1 (48a229cea 2026-09-01) (Homebrew) 
  $ cargo --version
    cargo 1.98.1 (797e8a9bc 2026-08-05) (Homebrew) 
  $ rustc --version --verbose
    rustc 1.98.1 (48a229cea 2026-09-01) (Homebrew)
    binary: rustc
    commit-hash: 48a229ceaefd4985c50990b14116b6d856af0985
    commit-date: 2026-09-01
    host: aarch64-apple-darwin
    release: 1.98.1
    LLVM version: 22.1.8

rustc 自带的东西

实测 · 本机执行输出
  $ rustc --print sysroot → /opt/homebrew/Cellar/rust/1.98.1
  sysroot 顶层: ['.bottle', '.brew', 'COPYRIGHT', 'INSTALL_RECEIPT.json', 'LICENSE-APACHE', 'LICENSE-MIT', 'README.md', 'bin', 'etc', 'lib', 'libexec', 'license-metadata.json', 'sbom.spdx.json', 'share']
  lib/rustlib 下: ['aarch64-apple-darwin', 'components', 'etc', 'rust-installer-version', 'src']
  已安装标准库的目标平台: ['aarch64-apple-darwin', 'etc'] (只有宿主平台)
  标准库文件: {'.dylib': '1,326,976 字节', '.rlib': '3,260,096 字节', '.rmeta': '8,361,025 字节'}
  $ rustc --print target-list → rustc 认识 330 个目标三元组(但只有 2 个装了标准库)

标准库是随编译器分发的预编译库(rlib),不是每次编译重新编译的。

cargo 如何调用 rustc

实测 · 本机执行输出
  $ cargo build -v
       Compiling verbose v0.1.0 (<实验目录>/proj/verbose)
    Running rustc 的参数(省略了 --check-cfg):
      rustc --crate-name verbose --edition=2024 src/main.rs --error-format=json
      --json=diagnostic-rendered-ansi,artifacts,future-incompat --crate-type bin --emit=dep-info,link
      -C embed-bitcode=no -C debuginfo=2 -C split-debuginfo=unpacked -C metadata=10e6bdd0d2a08525 -C
      extra-filename=-5115401704f9e5a2 --out-dir <实验目录>/target/debug/deps -C
      incremental=<实验目录>/target/debug/incremental -L dependency=<实验目录>/target/debug/deps
        Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.21s

这些参数的含义会在后面的文章里陆续展开,比如Cargo Profile(debuginfo、opt-level)与增量编译(-C incremental)。

绕过 cargo、换掉 rustc

实测 · 本机执行输出
  $ rustc --edition=2024 src/main.rs -o verbose_direct  (0.09 s,退出码 0)
  运行: Hello, world! | 文件大小 434752 字节;cargo debug 产物 438120 字节
  $ RUSTC=/nonexistent/rustc cargo build →
    error: could not execute process `/nonexistent/rustc -vV` (never executed)
    
    Caused by:
      No such file or directory (os error 2)
  $ rustc +nightly src/main.rs("+toolchain" 是 rustup 的代理才认识的写法):
    error: multiple input filenames provided (first two filenames are `+nightly` and `<实验目录>/proj/verbose/src/main.rs`) [退出码 1]

rustup 的作用(多版本工具链、+nightly、交叉编译目标的安装)我没有在本机验证,因为没有装它。

分步演示

rustc、cargo 与 rustup
本步的对象

    本文用到的工具与边界

    • 本机 macOS 27 arm64 / rustc 1.98.1(brew)/ cargo 1.98.1;单个文件用 rustc 直接编译,需要依赖时用 cargo(经代理从 crates.io 下载);计时用 std::time::Instant,数字每次运行会有小幅抖动。本机没有 rustup,工具链来自 Homebrew
    • 没有验证:rustup 的行为(toolchain 切换、target add、component add)、nightly 与 stable 的差别、rust-toolchain.toml 的作用、Windows 与 Linux 上的安装方式、cargo 对其它编译器包装(RUSTC_WRAPPER)的支持
    京ICP备2026067502号-1京公网安备11010502063487号