DEBUG.WIKI
ZgoCloud:多地区部署,按需选节点;日本、美国、香港、德国
PanstarCloud:部署应用,接入 AI,云服务器与 AI 网关
OnlineSIM:在线接收短信,虚拟号码租用

Cargo nightly 跨 CARGO_HOME 缓存命中后仍反复编译

Cargo 1.101-nightly 配合修改版 sccache 跨 Cargo home 路径恢复产物时,旧 dep-info 绝对路径可引起重复编译。统一路径或隔离缓存复用范围,保留真实依赖失效检查。

远程编译缓存显示命中,第二次执行 Cargo 构建却又重新请求相同产物。若使用 Cargo 1.101-nightly,并在不同 CARGO_HOME 路径之间共享 rustc 输出缓存,应检查恢复出来的 dep-info 是否仍指向另一台机器的源码目录。

这条具体场景使用了支持跨工作区复用的 sccache 修改版。它不是所有稳定版 Cargo 或所有 sccache 配置都会发生的回归;只有共享输出中保留了旧绝对路径,且本机没有该路径时,才符合下面的循环。

缓存命中与依赖新鲜度是两层判断

rustc 生成的 .d 文件可以包含依赖源码的绝对路径。Cargo 随后把它转换成自己的指纹信息,尽量将当前包目录和构建目录里的路径变成相对路径,以便移动工作区或 target 目录。

在该 nightly 快照中,旧路径既不属于当前包根,也不属于当前构建目录时,会保留为绝对路径。假设缓存中的依赖来自 /build-a/cargo/registry/src/.../lib.rs,当前机器却使用 /build-b/cargo,Cargo 再检查旧路径会发现文件不存在,认定依赖需要重新构建。包装器接着又恢复同一份 .d,下一次仍然失败。

因此,命中率很高并不能证明构建已经跳过。需要同时看 Cargo 是否反复安排同一个编译单元、包装器是否反复下载同一产物,以及 .d 中的路径能否在当前环境解析。只记录路径和工具版本,不上传整个 Cargo home;其中可能包含登录凭据。

先隔离不兼容的缓存复用范围

可控制 CI 布局时,让共享产物的工作区使用一致的 Cargo home 绝对路径,并确认依赖确实位于相同位置。否则,在缓存提供方的既有配置里区分不同 Cargo home 或主机构建环境,不再把带旧路径的 rustc 输出交叉恢复。

这会减少跨机器命中,但能先停止错误产物反复恢复。具体缓存键和失效操作取决于包装器及远程缓存服务,不存在一条通用 Cargo 开关可以安全替它们完成迁移。变更前保留原缓存策略和一个失败产物的校验值;只使受影响的缓存命名空间失效,避免清空其他项目仍在使用的共享缓存。

若需要重新生成本机指纹与构建输出,应先停止对应工作区的并发构建,并沿项目已有的定向清理流程处理本任务可丢弃产物。单独删除本机 target、下一次又恢复同一个旧路径 .d,不能解决循环;同样,不应创建指向任意旧机器目录的假链接来让检查侥幸通过。

不手工改写 Cargo 私有指纹格式

Cargo home 的内部布局和指纹文件格式都不是稳定接口。不要直接改二进制 dep-info、删除所有依赖文件检查,或用 --remap-path-prefix 推断 .d 必然会按远程缓存所需方式重写。依赖文件可能引用工作区之外的真实输入,忽略它们会让构建错误地复用旧结果。

这里的判断依据限于 1.101-nightly 的具体源码路径。后续若采用工具链或包装器修正,先核对实际版本及缓存格式兼容性,再重新放开跨路径共享,不能把一个开发方案当作已发布稳定能力。

验收在同一机器、同一输入上连续构建两次,再覆盖项目确实需要支持的两种 Cargo home 布局。第二次应不再因不存在的旧路径重复安排编译;同时修改真实依赖输入,确认仍会正确失效。只看到缓存命中或总耗时偶然下降,都不能单独证明依赖判断已恢复。