学无止境

少年辛苦终身事,莫向光阴惰寸功。——唐·杜荀鹤《题弟侄书堂》


Rust 与 Cargo 清理指南:删除旧工具链和构建缓存

Rust 项目编译一段时间后,磁盘空间往往会被以下三类文件占满:

  1. 项目中的 target/ 构建产物;
  2. Cargo 保存在 $CARGO_HOME(通常是 ~/.cargo/)中的依赖缓存;
  3. rustup 安装的旧工具链、交叉编译目标和组件。

它们的用途和清理方式并不相同。本文将分别介绍如何安全清理这些文件,并尽量避免不必要的重新下载和完整编译。

建议先检查占用,再使用工具提供的 --dry-run 预览结果。不要直接手动删除整个 ~/.cargo/~/.rustup/ 目录。

一、先找出空间占用来源

在 Linux 和 macOS 中,可以先查看 Rust 相关目录的大小:

du -sh target 2>/dev/null
du -sh "${CARGO_HOME:-$HOME/.cargo}" 2>/dev/null
du -sh "${RUSTUP_HOME:-$HOME/.rustup}" 2>/dev/null

常见目录的作用如下:

位置 内容 清理后的影响
项目/target/ 当前项目的编译产物 下次构建需要重新编译
$CARGO_HOME/registry/ crates.io 索引、.crate 包和解压后的源码 后续可能重新下载或解压依赖
$CARGO_HOME/git/ Git 依赖的仓库与检出内容 后续需要重新获取 Git 依赖
$CARGO_HOME/bin/ cargo install 安装的程序 删除后相应命令将无法使用
$RUSTUP_HOME/toolchains/ Rust 工具链 删除后无法再使用对应版本

二、清理项目的 target/ 构建产物

1. 使用 Cargo 原生命令

不带参数的 cargo clean 会删除整个目标目录:

cargo clean

这是释放空间最彻底的方式,但下一次执行 cargo buildcargo testcargo run 时,所有依赖都需要重新编译。

如果只想清理一部分产物,可以缩小范围。

清理指定包

cargo clean -p package_name

-p 接收的是 Cargo 包名,适合工作空间或只想删除某个依赖相关产物的场景。它并不保证只删除“某个旧版本”的文件;如果存在同名多版本依赖,应使用完整的 package ID 进一步消除歧义。

按构建配置清理

# 清理 dev profile(通常对应 target/debug)
cargo clean --profile dev

# 清理 release 产物
cargo clean --release

还可以只清理文档或指定编译目标:

# 清理 target/doc
cargo clean --doc

# 清理指定目标平台的构建产物
cargo clean --target aarch64-unknown-linux-gnu

较新的 Cargo 支持在执行前预览:

cargo clean --dry-run --verbose

如果配置了 CARGO_TARGET_DIRbuild.target-dir,构建产物可能不在项目内的 target/ 中。cargo clean 会遵循 Cargo 的目标目录配置,比手动执行 rm -rf target 更可靠。

2. 批量清理多个 Rust 项目

如果本机有大量 Rust 项目,可以使用 cargo-clean-all 递归查找并清理 target/

cargo install cargo-clean-all

先扫描并预览可释放空间:

cargo clean-all --dry-run --keep-days 30 ~

确认后再执行:

cargo clean-all --keep-days 30 ~

该命令会保留最近 30 天内编译过的项目,并在真正删除前要求确认。也可以使用交互模式手动选择:

cargo clean-all --interactive ~

扫描整个家目录可能比较慢,还可能遍历不相关目录。实际使用时,最好将路径限制在源码目录,例如:

cargo clean-all --keep-days 30 ~/code

3. cargo-sweep:可用,但不再优先推荐

cargo-sweep 可以按时间、工具链或目录大小清理 target/ 中的部分产物:

cargo install cargo-sweep

# 预览超过 30 天未使用的产物
cargo sweep --dry-run --time 30

# 确认后执行
cargo sweep --time 30

# 清理由未安装工具链生成的产物
cargo sweep --installed

不过,该项目目前已明确标记为停止维护,并建议用户考虑 cargo-clean-all。如果只是偶尔清理,优先使用 Cargo 原生的 cargo clean;需要批量清理项目时,则优先考虑 cargo-clean-all

三、清理 Cargo 全局依赖缓存

Cargo 的全局缓存位于 $CARGO_HOME,默认是 ~/.cargo/。它主要保存注册表索引、下载的 .crate 文件、解压后的源码和 Git 依赖。

这些文件不是项目的编译结果。清理它们通常不会修复编译错误,只会释放磁盘空间,并让后续构建重新下载或解压依赖。

1. 优先使用 Cargo 内置的自动垃圾回收

Rust/Cargo 1.88 开始,Cargo 的全局缓存自动垃圾回收(GC)已稳定启用。Cargo 会记录缓存项的使用情况,并定期删除长期未使用的数据。

先确认版本:

cargo --version

如果使用的是较新版本,并且磁盘空间并不紧张,通常无需频繁手动清理 $CARGO_HOME。自动 GC 只管理 Cargo 的全局缓存,不会替你删除各个项目的 target/,也不会卸载 rustup 工具链。

2. 使用 cargo-cache 查看和手动清理

需要立即释放空间时,可以安装 cargo-cache

cargo install cargo-cache

查看缓存组成,不执行删除:

cargo cache

列出占用最大的项目:

cargo cache --top-cache-items 10

先预览轻量清理:

cargo cache --dry-run --autoclean

确认后执行:

cargo cache --autoclean

--autoclean 主要删除已经解压的 crate 源码和 Git checkout,同时保留可用于恢复它们的 .crate 压缩包与 Git 数据库。因此,它通常比全量删除更温和。

如果确实要删除全部 Cargo 缓存,可以先预览:

cargo cache --dry-run --remove-dir all

确认后再执行:

cargo cache --remove-dir all

cargo cache -acargo cache --autoclean 的短参数,并不表示“删除全部缓存”。全量清理使用的是 --remove-dir all

此外,~/.cargo/bin/ 中保存的是 cargo install 安装的可执行程序,不应当作普通缓存直接删除。卸载某个程序应使用:

cargo uninstall package_name

四、清理 rustup 旧工具链与组件

cargo clean 和 Cargo 缓存 GC 都不会删除 rustup 安装的工具链。多套 stable、beta、nightly、固定版本和交叉编译组件可能让 ~/.rustup/ 占用大量空间。

1. 查看已安装工具链

rustup toolchain list

输出可能类似:

stable-x86_64-unknown-linux-gnu (active, default)
nightly-x86_64-unknown-linux-gnu
1.85.0-x86_64-unknown-linux-gnu
nightly-2025-01-01-x86_64-unknown-linux-gnu

先确认项目是否通过 rust-toolchain.toml、目录级 override 或 CI 配置依赖某个固定版本,再卸载不用的工具链:

rustup toolchain uninstall 1.85.0-x86_64-unknown-linux-gnu
rustup toolchain uninstall nightly-2025-01-01-x86_64-unknown-linux-gnu

不要卸载 rustup show active-toolchain 显示的当前活动工具链,除非已经准备好替代版本。

2. 检查目录级 override

某些目录可能绑定了特定工具链:

rustup override list

如果某条 override 已不再需要,可以进入对应目录后移除:

rustup override unset

移除 override 不会自动卸载工具链。确认没有其他项目使用后,再执行 rustup toolchain uninstall

3. 删除不需要的组件和交叉编译目标

查看当前工具链的已安装组件:

rustup component list --installed

删除不需要的组件:

rustup component remove rust-src
rustup component remove llvm-tools-preview

查看已安装的目标平台:

rustup target list --installed

删除不再使用的交叉编译目标:

rustup target remove aarch64-unknown-linux-gnu
rustup target remove wasm32-unknown-unknown

如果组件或目标属于某个非默认工具链,可以通过 --toolchain 精确指定:

rustup target remove wasm32-unknown-unknown --toolchain nightly

五、推荐的清理流程

日常维护

通常不必定期清空缓存。项目构建产物过大时,先执行:

cargo clean --dry-run --verbose

然后按需要清理指定 profile、包或完整 target/

多项目占用过大

对集中存放源码的目录执行:

cargo clean-all --dry-run --keep-days 30 ~/code
cargo clean-all --keep-days 30 ~/code

Cargo 全局缓存告急

先查看占用,再进行轻量清理:

cargo cache
cargo cache --dry-run --autoclean
cargo cache --autoclean

只有在磁盘空间非常紧张,并且可以接受重新下载依赖时,才考虑:

cargo cache --dry-run --remove-dir all
cargo cache --remove-dir all

rustup 占用过大

rustup toolchain list
rustup override list
rustup target list --installed
rustup component list --installed

根据实际依赖逐项卸载旧工具链、目标和组件,而不是直接删除 ~/.rustup/

总结

Rust 的磁盘占用需要分层处理:

  • 项目编译产物:使用 cargo clean,多项目场景使用 cargo-clean-all
  • Cargo 全局依赖缓存:优先依赖 Cargo 1.88+ 的自动 GC,紧急时使用 cargo-cache
  • 旧 Rust 工具链:使用 rustup toolchain uninstall
  • 多余组件和目标平台:使用 rustup component removerustup target remove

最重要的原则是:先查看、再预览、最后删除。清理缓存可以换回磁盘空间,但代价通常是下一次构建需要重新下载依赖或重新编译。