如何避免 Rust 项目中的依赖地狱?

fsq*_*rel 0 dependencies rust rust-crates rust-cargo

我正在开发一个依赖于许多第 3 方板条箱的项目。\n正如经常发生的那样,第 3 方板条箱依赖于其他板条箱。

\n

我经常发现自己处于这样的情况:两个或多个板条箱需要同一个板条箱的不同版本。因此,cargo 无法选择版本。\n通常,有问题的 crate 是我没有明确添加的 crate。

\n

同时,唯一的解决方案是检查第三方并更新那里的版本,但这通常需要更新整个第三方链。这需要时间而且不好玩。当我尝试将更改发布到上游时,需要很长时间才能合并它们。

\n

Rust 有没有更好的方法来处理这种情况?

\n

PS 我有 C++ 背景,其中依赖管理更糟糕。所以,我对现代生态系统没有太多经验,可能会错过一些东西。

\n

为了提供更多上下文,我添加了部分(完整版本很长)cargo tree输出。

\n

这是我添加新依赖项之前的树:

\n
    \xe2\x94\x82   \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 near-chain-configs v0.0.0 (https://github.com/f-squirrel/nearcore.git?rev=76424c004de84f6b5823751f132f62a0da9aa656#0a8e7ac7)\n    \xe2\x94\x82   \xe2\x94\x82   \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 anyhow v1.0.75 (*)\n    \xe2\x94\x82   \xe2\x94\x82   \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 chrono v0.4.26 (*)\n    \xe2\x94\x82   \xe2\x94\x82   \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 derive_more v0.99.17 (proc-macro) (*)\n    \xe2\x94\x82   \xe2\x94\x82   \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 near-config-utils v0.0.0 (https://github.com/f-squirrel/nearcore.git?rev=76424c004de84f6b5823751f132f62a0da9aa656#0a8e7ac7)\n    \xe2\x94\x82   \xe2\x94\x82   \xe2\x94\x82   \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 anyhow v1.0.75 (*)\n    \xe2\x94\x82   \xe2\x94\x82   \xe2\x94\x82   \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 json_comments v0.2.1\n    \xe2\x94\x82   \xe2\x94\x82   \xe2\x94\x82   \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 thiserror v1.0.47 (*)\n    \xe2\x94\x82   \xe2\x94\x82   \xe2\x94\x82   \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 tracing v0.1.37 (*)\n    \xe2\x94\x82   \xe2\x94\x82   \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 near-crypto v0.0.0 (https://github.com/f-squirrel/nearcore.git?rev=76424c004de84f6b5823751f132f62a0da9aa656#0a8e7ac7)\n    \xe2\x94\x82   \xe2\x94\x82   \xe2\x94\x82   \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 blake2 v0.9.2 (*)\n    \xe2\x94\x82   \xe2\x94\x82   \xe2\x94\x82   \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 borsh v0.10.3 (*)\n    \xe2\x94\x82   \xe2\x94\x82   \xe2\x94\x82   \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 bs58 v0.4.0\n    \xe2\x94\x82   \xe2\x94\x82   \xe2\x94\x82   \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 c2-chacha v0.3.3\n    \xe2\x94\x82   \xe2\x94\x82   \xe2\x94\x82   \xe2\x94\x82   \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 cipher v0.2.5\n    \xe2\x94\x82   \xe2\x94\x82   \xe2\x94\x82   \xe2\x94\x82   \xe2\x94\x82   \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 generic-array v0.14.7 (*)\n    \xe2\x94\x82   \xe2\x94\x82   \xe2\x94\x82   \xe2\x94\x82   \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 ppv-lite86 v0.2.17\n    \xe2\x94\x82   \xe2\x94\x82   \xe2\x94\x82   \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 curve25519-dalek v3.2.0 (*)\n    \xe2\x94\x82   \xe2\x94\x82   \xe2\x94\x82   \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 derive_more v0.99.17 (proc-macro) (*)\n    \xe2\x94\x82   \xe2\x94\x82   \xe2\x94\x82   \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 ed25519-dalek v1.0.1\n    \xe2\x94\x82   \xe2\x94\x82   \xe2\x94\x82   \xe2\x94\x82   \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 curve25519-dalek v3.2.0 (*)\n    \xe2\x94\x82   \xe2\x94\x82   \xe2\x94\x82   \xe2\x94\x82   \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 ed25519 v1.5.3\n    \xe2\x94\x82   \xe2\x94\x82   \xe2\x94\x82   \xe2\x94\x82   \xe2\x94\x82   \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 signature v1.6.4\n
Run Code Online (Sandbox Code Playgroud)\n

这是我添加的依赖项:

\n
    \xe2\x94\x82   \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 near-chain-configs v0.0.0 (https://github.com/f-squirrel/nearcore.git?rev=76424c004de84f6b5823751f132f62a0da9aa656#0a8e7ac7)\n    \xe2\x94\x82   \xe2\x94\x82   \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 anyhow v1.0.75 (*)\n    \xe2\x94\x82   \xe2\x94\x82   \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 chrono v0.4.26 (*)\n    \xe2\x94\x82   \xe2\x94\x82   \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 derive_more v0.99.17 (proc-macro) (*)\n    \xe2\x94\x82   \xe2\x94\x82   \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 near-config-utils v0.0.0 (https://github.com/f-squirrel/nearcore.git?rev=76424c004de84f6b5823751f132f62a0da9aa656#0a8e7ac7)\n    \xe2\x94\x82   \xe2\x94\x82   \xe2\x94\x82   \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 anyhow v1.0.75 (*)\n    \xe2\x94\x82   \xe2\x94\x82   \xe2\x94\x82   \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 json_comments v0.2.1\n    \xe2\x94\x82   \xe2\x94\x82   \xe2\x94\x82   \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 thiserror v1.0.47 (*)\n    \xe2\x94\x82   \xe2\x94\x82   \xe2\x94\x82   \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 tracing v0.1.37 (*)\n    \xe2\x94\x82   \xe2\x94\x82   \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 near-crypto v0.0.0 (https://github.com/f-squirrel/nearcore.git?rev=76424c004de84f6b5823751f132f62a0da9aa656#0a8e7ac7)\n    \xe2\x94\x82   \xe2\x94\x82   \xe2\x94\x82   \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 blake2 v0.9.2 (*)\n    \xe2\x94\x82   \xe2\x94\x82   \xe2\x94\x82   \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 borsh v0.10.3 (*)\n    \xe2\x94\x82   \xe2\x94\x82   \xe2\x94\x82   \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 bs58 v0.4.0\n    \xe2\x94\x82   \xe2\x94\x82   \xe2\x94\x82   \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 c2-chacha v0.3.3\n    \xe2\x94\x82   \xe2\x94\x82   \xe2\x94\x82   \xe2\x94\x82   \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 cipher v0.2.5\n    \xe2\x94\x82   \xe2\x94\x82   \xe2\x94\x82   \xe2\x94\x82   \xe2\x94\x82   \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 generic-array v0.14.7 (*)\n    \xe2\x94\x82   \xe2\x94\x82   \xe2\x94\x82   \xe2\x94\x82   \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 ppv-lite86 v0.2.17\n    \xe2\x94\x82   \xe2\x94\x82   \xe2\x94\x82   \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 curve25519-dalek v3.2.0 (*)\n    \xe2\x94\x82   \xe2\x94\x82   \xe2\x94\x82   \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 derive_more v0.99.17 (proc-macro) (*)\n    \xe2\x94\x82   \xe2\x94\x82   \xe2\x94\x82   \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 ed25519-dalek v1.0.1\n    \xe2\x94\x82   \xe2\x94\x82   \xe2\x94\x82   \xe2\x94\x82   \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 curve25519-dalek v3.2.0 (*)\n    \xe2\x94\x82   \xe2\x94\x82   \xe2\x94\x82   \xe2\x94\x82   \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 ed25519 v1.5.3\n    \xe2\x94\x82   \xe2\x94\x82   \xe2\x94\x82   \xe2\x94\x82   \xe2\x94\x82   \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 signature v1.6.4\n
Run Code Online (Sandbox Code Playgroud)\n

我收到的错误:

\n
error: failed to select a version for `signature`.\n    ... required by package `ecdsa v0.16.0`\n    ... which satisfies dependency `ecdsa-core = "^0.16"` of package `k256 v0.13.1`\n    ... which satisfies dependency `k256 = "^0.13"` of package `iota-crypto v0.21.2`\n    ... which satisfies dependency `iota-crypto = "^0.21.2"` of package `stronghold_engine v2.0.0-rc.0`\n    ... which satisfies dependency `engine = "^2.0.0-rc.0"` of package `iota_stronghold v2.0.0`\n    ... which satisfies dependency `iota_stronghold = "^2.0.0"` of package `iota-sdk v1.1.0`\n    ... which satisfies dependency `iota-sdk = "^1.1.0"` of package `iota_client v0.1.0 (/my_lib/iota_client)`\n    ... which satisfies path dependency `iota_client` (locked to 0.1.0) of package `lib_my_lib v0.1.0 (/my_lib/lib_my_lib)`\n    ... which satisfies path dependency `lib_my_lib` (locked to 0.1.0) of package `my_lib v0.1.0 (/my_lib/my_lib)`\nversions that meet the requirements `^2.0, <2.1` are: 2.0.0\n\nall possible versions conflict with previously selected packages.\n\n  previously selected package `signature v2.1.0`\n    ... which satisfies dependency `signature = "^2"` of package `ed25519 v2.2.2`\n    ... which satisfies dependency `ed25519 = "^2.2.0"` of package `ed25519-zebra v4.0.3`\n    ... which satisfies dependency `ed25519-zebra = "^4.0.1"` of package `iota-crypto v0.23.0`\n    ... which satisfies dependency `iota-crypto = "^0.23.0"` of package `iota-sdk v1.1.0`\n    ... which satisfies dependency `iota-sdk = "^1.1.0"` of package `iota_client v0.1.0 (/my_lib/iota_client)`\n    ... which satisfies path dependency `iota_client` (locked to 0.1.0) of package `lib_my_lib v0.1.0 (/my_lib/lib_my_lib)`\n    ... which satisfies path dependency `lib_my_lib` (locked to 0.1.0) of package `my_lib v0.1.0 (/my_lib/my_lib)`\n\nfailed to select a version for `signature` which could resolve this conflict\n
Run Code Online (Sandbox Code Playgroud)\n

更新:

\n

我曾尝试cargo update在添加新依赖项之前运行以更新版本signature (由Kevin Reid建议),但它没有更新版本。

\n

Kev*_*eid 5

这不是一次典型的经历;在这种情况下,责任应该归咎于ecdsa对其依赖项之一有版本要求。< <=要求导致包可能无法与同一版本中的其他包编译,因此在已发布的包中不是良好的做法。

\n

<=要求仅应在以下情况下使用:

\n
    \n
  • 后续版本的依赖包有一个bug需要避免,
  • \n
  • 依赖项是一个 \xe2\x80\x9cinternal\xe2\x80\x9d 库(例如宏库),任何其他包都不应该依赖它,或者
  • \n
  • 您正在组织内编写非公共库,您可以在其中管理整个依赖关系图中的冲突。
  • \n
\n

ecdsa似乎没有记录为什么它有这个要求,我认为他们的文档中遗漏了这一点。但是,此提交ecdsa表明 或更高版本v0.16.5(这是 semver 兼容的更新)应该允许使用signature v2.1.0并解决此冲突。

\n

您可以尝试实现此状态的一件事是在添加新依赖项cargo update 之前运行,以防问题是由Cargo.lock文件中已写入的依赖项版本提示的。

\n