内容提要
cargoc 是管理 Rust 项目中间构建缓存的工具:它将 Cargo 的 build-dir 集中到专用缓存根,按工作区记录并清理空闲缓存,最终产物仍留在原 target-dir。清理时通过租约和 Cargo 原生锁保护正在使用的缓存,锁忙则跳过。默认设 80 GiB 软预算和 7 天过期,超限时从最久未用的工作区开始清理。它不提升编译速度,也不复用依赖,只回收可重建的中间文件。
延伸解读
清理边界:中间缓存与最终产物分离
cargoc 的核心思路是把 Cargo 的 build-dir 集中到专用缓存根,而 target-dir 中的最终产物保持原位。这意味着清理操作只针对可重建的中间文件,不会误删需要保留的程序或库。但要注意,旧 target 目录不会自动迁移或缩小,安装后仍需手动处理历史遗留。
安全机制:租约与锁避免误删活跃缓存
清理器不会仅凭时间判断缓存是否空闲。它通过工作区租约和 Cargo 原生锁双重保护,遇到锁忙的缓存直接跳过。构建退出时也严格按顺序释放资源,确保子进程不会在清理时仍访问缓存。这种设计宁愿暂时达不到空间目标,也不冒险删除正在使用的目录。
预算与阈值:软限制而非硬配额
默认 80 GiB 软预算和 7 天过期是清理策略的起点,而非硬性配额。压力清理的低水位比例 0.8 意味着目标约为 64 GiB,但实际释放量受活跃缓存、候选不足或缓存卷位置影响。此外,缓存卷保留 20 GiB 空间和 1 GiB 紧急阈值只保护缓存卷和当前调用,不覆盖最终产物、依赖下载或整机磁盘。
使用注意:命令差异与接管范围
cargoc clean 只清理空闲的受管理中间缓存,而 cargoc exec clean 会转发给 Cargo 原生 clean,可能删除最终产物。启用 PATH 接管后,普通 cargo 命令会经过代理,但 IDE 或脚本若写死真实 Cargo 路径仍可能绕过。旧 target 或旧版 build-dir 不会被自动接管,需由原所有者单独处理。
Q&A
cargoc 是做什么的?它和直接删除 target 目录有什么区别?
cargoc 是管理 Rust 项目中间构建缓存的工具。它将 Cargo 的 build-dir 集中到专用缓存根,按工作区记录并清理空闲缓存,最终产物仍留在原 target-dir。直接删除 target 目录会连最终产物一起删掉,而 cargoc 只清理可重建的中间文件。
cargoc 清理缓存时如何避免删掉正在编译的目录?
cargoc 通过三层保护:当前工作区持有租约,自动清理会显式保护它;清理候选时需取得候选工作区的租约和扫描到的 Cargo 原生锁;包装器停止构建时只关闭本次调用拥有的进程组或 Windows Job。遇到锁忙的缓存会跳过,不会强删正在使用的目录。
cargoc 的默认磁盘预算和过期策略是怎样的?
默认给受管理的中间缓存设置 80 GiB 软预算,超过预算或缓存卷剩余空间低于期望值时,自动清理会从较久未使用的工作区开始处理。默认超过 7 天未使用的缓存也可能因过期被清理。压力清理的低水位比例默认是 0.8,即目标容量为 64 GiB。
cargoc clean 和 cargo clean 有什么不同?
cargoc clean 清理的是空闲的受管理中间缓存,最终产物不在删除范围内。而 cargo clean 是 Cargo 原生命令,可能删除目标目录中的最终产物。执行 cargoc exec clean 会转发给 Cargo 原生的 clean,可能删除最终产物。
安装 cargoc 后如何开始使用?需要哪些前置条件?
受管理构建需要 Cargo 1.91+。安装后先运行 cargo --version 和 cargoc --version 检查版本,然后执行 cargoc init 初始化配置(默认创建 $CARGO_HOME/cargoc.toml)。进入 Rust 工作区后,从显式调用开始:cargoc build、cargoc status、cargoc clean --dry-run,确认范围后再执行 cargoc clean。
cargoc 能提升编译速度或复用依赖吗?
不能。cargoc 不提升编译速度,也不复用依赖,它只回收可重建的中间文件。空间回收来自删除空闲中间缓存,代价是之后可能重新编译。它也不负责最终产物、Cargo 下载缓存或整台机器的磁盘配额。
启用 cargoc 的 PATH 接管后,普通 cargo 命令会有什么变化?
启用接管后,输入 cargo build、cargo test 等命令会通过用户目录中的 shim/代理转发给 cargoc 管理的构建,代理会转发参数和退出码。但 IDE 或脚本如果写死真实 Cargo 的绝对路径,或使用 rustup run <toolchain> cargo ...,仍可能绕过接管。执行 cargoc setup --disable 可移除接管。