DEBUG.WIKI
Evoxt;最高 6.0GHz CPU;高频云服务器 · 免费每周备份;查看配置 →
OnlineSIM:在线接收短信,虚拟号码租用
RackNerd;$21.99/年 · 1GB KVM

cargo check 一直等构建目录锁:检查 build.rs 里的递归 Cargo

设置 CARGO_TARGET_DIR 后 cargo check 不再前进,先找是否由 build.rs 再次调用 Cargo,并检查父子构建是否等待同一个输出目录。

cargo check 停在 Blocking waiting for file lock on build directory,不再继续编译。若刚设置了统一的 CARGO_TARGET_DIR,先看构建脚本是否又启动了一个 Cargo:父构建还没结束,子构建就要写同一个目录,等待可能一直持续。

在 Cargo 1.98.1 中遇到这个症状,且 build.rs 内再次调用 cargo xtask 时,应检查父子进程是否继承了相同的输出目录。统一目录会让这些调用使用同一套输出;若子构建要获取父构建仍持有的锁,就会相互等待。仅凭环境变量与等待日志,不能认定所有同类卡住都是这个原因。

找到是谁在等谁

先保留当前输出,并查看进程的父子关系。另一个终端、IDE 或 CI 作业正在正常编译时,短暂等待是合理的,不能看到锁就删文件。

需要补日志时,在停止本次挂起构建后,从同样的工作目录单独运行:

cargo check -vv

这会真实执行项目的构建脚本,应先审查依赖和脚本。关注最后一条带包名前缀的输出、build.rs 发起的外部程序,以及是否出现第二个 Cargo。若构建脚本日志刚输出若干 cargo:rerun-if-changed,随后子 Cargo 等待,而父 Cargo 等它退出,就应处理递归依赖。

把生成步骤移到父构建之前

优先让 xtask 成为外部入口:先完成代码生成,再启动主项目的 cargo check。不要让主项目编译途中,回头要求同一工作区完成另一次主项目构建。修改前保留 build.rs、任务脚本和 CI 配置的版本,确认哪些生成文件是后续编译的前提。

若确实需要在构建脚本中编译一个独立工具,应明确它的依赖边界,并为它使用单独的输出目录。只换目录却仍让工具依赖当前正在构建的包,可能把锁等待变成无限递归或重复编译;这不是完整修复。

在 Rust 构建脚本中调用 Cargo 时,用 CARGO 环境变量定位当前工具链,避免硬编码 PATH 中另一个 cargo。这能消除工具链混用,但不会解除共享目录锁,必须同时解决输出目录和递归关系。

不要删除正在使用的锁,也不要清空整个 Cargo 缓存。当前持锁进程仍在运行时,删除文件无法让父子构建的依赖关系成立,还会干扰其他构建。

改动后从原触发入口复查:生成任务只运行预期次数,构建脚本能结束,主项目继续到编译完成。再验证正常入口和 CI 都能找到生成文件,且没有通过遗留产物“碰巧通过”。若改动破坏了生成顺序,恢复脚本配置后重新设计任务依赖,而不是恢复锁文件。