现象
报错 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。