3 个稳定版本
1.8.2 | 2021 年 11 月 2 日 |
---|---|
1.8.1 | 2021 年 10 月 26 日 |
1.8.0 | 2021 年 10 月 27 日 |
#8 在 #gemachain
每月 359 次下载
用于 gemachain-sdk
8KB
Cargo(截至 1.37)无法很好地处理树中多个其他crate的依赖crate的功能不同的场景。
为了说明问题,考虑以下按以下方式排列的crate A、B 和 C:
- Crate A 和 B 都是 Cargo 虚拟清单的成员
- Crate C 提供两个功能,F1 和 F2
- Crate A 请求 C 的功能 F1,crate B 请求 C 的功能 F2
当 crate A 和 B 一起构建时,cargo
会构建 C,同时启用功能 F1 和 F2(所有启用功能的并集)。然而,当 A 或 B 单独构建时,cargo
只会为 C 启用功能 F1 或 F2。
遗憾的是,在这些所有情况下,cargo
都会在同一个目标位置构建 crate C,并且每当 crate C 的功能改变时,C 的输出都会被重新创建。
从一个干净的工作区开始,首先单独构建 A 将会导致 C 如预期构建。然后单独构建 B,由于启用了 F2 而不是 F1,C 将会重新构建。现在重新构建 A,观察 C 也会重新构建,因为重新启用了 F1。
在实践中,这个问题要明显少得多,因为 A 和 B 很可能没有直接依赖于 C,间接导致了许多其他 crate 的重建。
gemachain-crate-features
通过显式声明所有“类似 C 的 crate”来提供一种解决“功能冲突”问题的方法,这些“类似 C 的 crate”包含了树中任何其他crate(无论是显式还是隐式)启用的所有功能的并集。Gemachain 源树中的所有crate都应该依赖于 gemachain-crate-features
。
添加新的依赖crate
当观察到不必要的 cargo
重建时,第一步是确定哪个依赖crate正在遭受功能冲突。
这个信息不能从标准的 cargo
程序中直接获得,因此使用以下步骤生成一个自定义的 cargo
程序,该程序在构建过程中将必要的功能信息输出到 stderr
$ git clone [email protected]:rust-lang/cargo.git -b rust-1.38.0
$ cd cargo
$ git apply 0001-Print-package-features.patch
$ cargo build
$ mv ~/.cargo/bin/cargo ~/.cargo/bin/cargo.org
$ cp ./target/debug/cargo ~/.cargo/bin/cargo
使用自定义的 cargo
重新构建,并搜索不同特性下构建的 crate 的指示(多次运行 ./scripts/cargo-install-all.sh
对此非常有效)。当确定有问题的 crate 时,将其作为 gemachain-crate-features
的依赖项添加,并包含该 crate 观察到的所有启用特性的并集。
附录
此命令将启用一些额外的 cargo 日志输出,有助于调试依赖问题。
export CARGO_LOG=cargo::core::compiler::fingerprint=info
依赖项
~17–33MB
~628K SLoC