huacnlee/cargo

Rust Cargo 的直接替代品

自动控制 target 大小的 Rust Cargo

huacnlee/cargo 是 Rust 构建工具 Cargo 的分支。安装后直接替换你的 cargo,不需要任何配置。git worktree 和项目之间共享构建产物,并自动控制在大小限制之内,所以尽管开 AI Agent,不用再删 target,也不会再从头编译。

$ curl -fsSL https://huacnlee.github.io/cargo/install.sh | sh

安装时会覆盖 ~/.cargo/bin/cargo,并把 rustup 代理保留为 cargo.rustup。cargo +nightly 和 rust-toolchain.toml 照常可用。用 --uninstall 运行脚本可以恢复代理。

安装一次,自动更新。执行命令后,cargo 最多每天一次在后台检查新版本并安装:校验 checksum,重命名替换,不输出任何内容。最近一次的结果在 ~/.cargo/.fork-update.log。设置 CARGO_FORK_AUTO_UPDATE=0 可以关闭;在 CI 中不会运行。

为什么做这个项目

Rust 是 AI 时代非常有价值的编程语言,但 target 成了我最头疼的问题:买了 2T 的硬盘都不够。试过的工具都没有解决,所以我直接改造了 Cargo。阅读完整背景。

第 5 天,没有手动删过任何东西

它现在跑在我的四台电脑上:两台 Linux、一台 macOS、一台 Windows(Windows 试得比较少)。在 Linux 和 macOS 上已经连续用了 5 天,跑满 worktree 做自动化 AI 开发。我再也没有清理过 target 目录,磁盘也再没有占满过。

Disktree 中主目录的磁盘占用图:~/.cargo/targets 占 99.5 GB 中的 41.7 GB,磁盘剩余 711.9 GB。
2026 年 11 月 4 日,我在 Omarchy 上的主目录,用 Disktree 查看。全部 Rust 构建产物 41.7 GB,所有代码和 worktree(work 目录)9.9 GB,磁盘剩余 711.9 GB。

Rust 的编译速度还是比 Go 这类语言慢一些。这个取舍我接受:我们慢一点,用户用起来更快。

我也在 X 上聊过这件事。

每个新 worktree 的成本都更低

525 个 crate 的 Rust workspace,5 个 git worktree,各构建一次。实测数据。

磁盘占用

5.1 GBCargo 为 33.6 GB,减少到 1/6.6

Cargo
33.6 GB
Fork
5.1 GB

构建时间

1.6 分钟Cargo 为 8.5 分钟,快 5.3 倍

Cargo
8.5 分钟
Fork
1.6 分钟

nsh 是一个 525 个 crate 的 workspace,每个 worktree 以 dev 配置构建一个二进制,8 核 Apple Silicon Mac,Rust 1.99 stable。同一 commit 的五个 worktree 跑一轮;编辑相关的数据取三次的中位数。关闭 sccache 等编译器缓存。

总磁盘占用 33.6 GB → 5.1 GB

12345

总构建时间 8.5 分钟 → 1.6 分钟

12345

每个 worktree 都是全新检出,构建一个二进制。Cargo 给每个 worktree 单独的 target 目录,并重新编译所有依赖。这个 fork 只编译一次并复用,所以之后的 worktree 只构建 workspace 里的 crate。

一个 worktree,首次构建

构建目录为空。差距主要来自依赖不再带调试信息。

Cargo
111.4 s
Fork
77.2 s

编辑核心 crate 后重新构建

在两个 worktree 的第二个里编辑 nsh-core,workspace 大部分都依赖它。速度和 Cargo 差不多,新 worktree 的首次编辑也一样;nightly 下使用 Cranelift。

Cargo
9.1 s
Fork
9.7 s
Fork,nightly
9.2 s

撤销编辑

文件和之前的一次构建相同,所以 fork 直接复用;Cargo 则重新编译这些 crate。

Cargo
8.8 s
Fork
3.4 s
Fork,nightly
3.2 s

不同项目也共享依赖

Cargo 1.99.0 和这个 fork 的 release 构建,在同一台机器上依次运行:nsh,然后 mado(独立仓库中 330 个 crate 的应用),再从空的构建目录构建一次 mado,相当于新 worktree 或 cargo clean 之后的情况。各跑一轮。

nsh,首次构建

构建目录为空。速度相同;依赖现在放进了共享目录。

Cargo
207.9 s
Fork
206.7 s

nsh 之后首次构建 mado

mado 的依赖用 opt-level 3 构建,nsh 用 0,所以两者几乎不共享(330 个 crate 中只有 1 个)。fork 更快是因为依赖不带调试信息。

Cargo
513.8 s
Fork
379.2 s

再次构建 mado,构建目录为空

Cargo 和首次构建一样重新编译全部 330 个 crate。fork 在共享目录中找到依赖,只编译 2 个 crate。

Cargo
513.8 s
Fork
16.2 s

nsh 和 mado 之后的磁盘占用

Cargo:两个 target 目录。Fork:两个项目目录(2.3 GB 和 0.4 GB)加共享依赖(2.2 GB)。

Cargo
10.3 GB
Fork
4.9 GB

清理是什么样的

构建之后,最多每小时一次,Cargo 删除一天内没有构建用过的内容,再按最近最少使用删除构建单元,直到项目符合限制。释放了空间时只输出一行。

$ cargo build
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 1.89s
     Cleaned 680 stale build units, 10.1GiB freed (build.gc)

有哪些改动

你的项目、Cargo.toml 和 .cargo/config.toml 都不用改。

修改默认设置
# ~/.cargo/config.toml
[build.gc]
max-size = "auto"      # or "15 GiB", "none"
shared-max-size = "50 GiB"
max-unused = "1 day"
shared-max-unused = "7 days"
frequency = "1 hour"   # or "always", "never"
enabled = true

设置 CARGO_SHARED_DEPS=0 把依赖留在项目的构建目录,CARGO_CHECK_SHARED_DEPS=0 在 cargo check 中只 check 依赖,CARGO_SHARE_WORKSPACE_UNITS=0 按 worktree 构建你的 crate,CARGO_DEV_CRANELIFT=0 在 nightly 上保留 LLVM,CARGO_RUSTC_THREADS=1 让前端单线程运行。