Rust 项目出现同名依赖多版本时,可以先跑 cargo tree -d

72 次浏览4 条回复

编译产物突然变大,或者两个库之间类型看着同名却不能互转时,可能是依赖树里同时进了多个版本。可以在项目根目录跑:

cargo tree -d

它只列出重复版本,比直接翻完整依赖树省事。想继续看某个版本是被谁引入的,可以指定包和版本:

cargo tree -i [email protected]

环境:Rust 1.44+ 自带的 Cargo。这个命令只读取依赖关系,不会修改 Cargo.lock;是否能统一版本还要看各上游 crate 的版本约束,别直接删锁文件碰运气。

这个命令我一般还会配 cargo tree -e features -i 包名 看一下 feature 是哪条链路打开的。

有时候不是版本约束本身的问题,而是某个默认 feature 把另一套依赖带进来了。先确认入口,再决定是关 default-features、统一 feature,还是只能等上游放宽版本,会少走一点弯路。

如果两条版本约束其实有交集,可以让 Cargo 试着只更新旧的那一份:

cargo update -p [email protected] --precise 1.0.210

目标版本不满足依赖约束时它会直接报错,比手改 Cargo.lock 稳妥。更新成功后还是要看一下锁文件 diff 并跑测试;如果上游约束确实互斥,就保留多版本或升级上游依赖。

workspace 里查这个时还可以先用 -p 限一下具体包,不然多个 member 的重复依赖混在一起会有点吵:

cargo tree -p my_crate -d

如果根因只在某个二进制或 example 上,这样看会清楚很多。后面再决定是调那个包的 feature,还是动 workspace 统一版本。

如果主要在查发布产物,建议再按依赖类型过滤一下:

cargo tree -d -e normal

这样能先排除只在测试或构建阶段出现的重复版本,免得看到 -d 就急着统一。要排查编译耗时则别过滤 build/dev 依赖,因为它们虽然通常不进最终二进制,仍可能拖慢构建。