4个稳定版本

1.8.12 2022年1月14日
1.7.17 2021年11月17日
1.6.18 2021年8月8日
1.6.16 2021年8月6日

#10 in #rebuild

Apache-2.0

8KB

Cargo(1.37版本)无法很好地处理树中多个依赖项的crate功能各不相同的情况。

为了说明这个问题,考虑如下安排的crate A、B和C:

  • Crate A和C都是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,C将被重新构建,因为启用了F2而不是F1。现在重新构建A,并观察C将再次被重新构建,因为F1被重新启用。

在实际应用中,这个问题远没有这么明显,因为A和B可能没有直接依赖于C,这可能导致其他许多crate的间接重建。

safecoin-crate-features通过明确声明所有“类似C的crate”,以显式地包含树中任何其他crate(无论是显式还是隐式)所启用的所有功能的并集,来解决这个问题。Safecoin源树中的所有crate都应该依赖于safecoin-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 时,将其添加到 safecoin-crate-features 的依赖中,并使用该 crate 观察到的所有已启用功能的并集。

附录

此命令将启用一些额外的 cargo 日志输出,这有助于调试依赖问题。

export CARGO_LOG=cargo::core::compiler::fingerprint=info

依赖

~17–29MB
~613K SLoC