← 中文资源

简体中文版本

Cargo 锁文件冲突 — failed to select a version

通过依赖树、--locked 构建与工具链检查,解决 Cargo 版本选择失败、锁文件过期和 links 原生库冲突。

阅读英文原文

现象

报错 failed to select a version for the requirement;提示 the lock file needs to be updated but --locked was passed;CI 或 Docker 构建失败而本地正常;出现 multiple packages link to native library openssl。

诊断

用反向依赖树找出约束来源,并显式复现锁文件问题:

cargo tree -i some-crate
cargo tree -d
cargo build --locked
rustc --version

cargo tree -i 列出每个依赖及其版本要求,两条分支要求区间不重叠就无解。cargo tree -d 显示重复版本,多数无害,但使用 links 的 crate 不能共存。cargo build --locked 的报错会指明哪个包的锁定版本已不满足清单,说明锁文件过期而非仓库不可用;同时确认固定工具链不旧于依赖声明的 rust-version。

根因

Cargo 无法同时满足所有版本要求:可能是两个依赖的 semver 区间冲突、修改 Cargo.toml 后锁文件过期、指定版本被 yank 或离线缓存缺失,或两个 crate 绑定同一原生库。

修复

让直接依赖的版本区间重叠,用精确版本更新,再重新生成并提交锁文件:

cargo update -p some-crate --precise 0.9.1
cargo update
cargo build
cargo build --locked

二进制项目要提交 Cargo.lock;CI 与 Docker 中在与编译相同的阶段生成锁文件,不要在锁文件过期时用 --locked 硬顶。links 冲突需要升级或替换其中一个原生绑定。cargo update 可能引入行为变化的传递依赖,升级后必须跑测试。

验证

在干净检出和 CI 镜像中执行 cargo build --locked 与 cargo test --locked,cargo tree -d 只剩可接受的重复,固定工具链仍满足所有 rust-version。