Managing Cargo dependencies - gfx-rs/wgpu GitHub Wiki

In general, WGPU tries to stay up-to-date with the current Rust ecosystem; we are interested in keeping the version of dependency crates' we use up-to-date. However, there are some considerations to keep in mind when upgrading or adding dependencies to WGPU.

Adding or upgrading dependencies may cause dependency duplication downstream

Some crates in the Rust ecosystem are useful for both WGPU and its downstream consumers. Popular crates—like those in the serde ecosystem, for example—are often used in multiple places in a Rust crate's dependency tree. Normally, Cargo can unify dependencies behind a single SemVer-compatible version. When one or more, but not all, of these places consume a SemVer-incompatible upgrade, Cargo uses both in the new dependency tree (see The Cargo Book's section titled Version-incompability hazards). These are often referred to as “duplicate dependencies”[^1].

[^1]: One can detect such duplicates with cargo tree --duplicates.

There exist many Rust projects that, for some reason or another, are sensitive to duplicate dependencies. The most common reason for this is to eliminate the number of built dependencies, but there are other valid reasons for doing so, like projects that prefer to vendor in their dependencies' source code and keep diffs easy to inspect. When a dependency of WGPU releases a SemVer-incompatible change and WGPU consumes it (even if it's new to WGPU), it may cause conflicts for projects that avoid duplicate dependencies.

Tip

Downstreams like Firefox can and do work around Cargo's (well-motivated) refusal to unify SemVer-incompatible versions of crates, but this happens only on a case-by-case basis. In general, this requires source compatibility for the APIs actually consumed between both versions.

Firefox needs to audit every dependency

In addition to the above, Firefox has unusual sensitivities to updates because of required auditing via cargo-vet. Firefox contributors cannot bring in a Rust dependency—including new versions of dependencies already in use—without an audit indicating that the dependency meets safe-to-deploy criteria for all of its feature combinations. One can ask the following questions to determine whether an upgrade is feasible for Firefox; “yes” answers are significantly easier cases to deal with:

  1. If the dependency had to be audited for safe-to-deploy, would it take less than an hour to review?

    One can use https://diff.rs/ to quickly gauge the answer to this question for upgrades. Example: serde 1.0.218 → 1.0.219

  2. Does the same code work between the two dependency's versions without needing to be changed (viz., are they "source-compatible")?

    NOTE: This is somewhat different from SemVer compatibility, because it deals with code already written, rather than SemVer's dealing with code that can might be written.

  3. Does the dependency already have an audit in Mozilla's supply-chain/audits.toml or in the other audit databases it imports in supply-chain/config.toml?

Tip

Searchfox can be used to answer question (3) and other simple questions with just a web browser. For example:

Tip

For more complicated questions like, “What features does Mozilla use in hashbrown crate?” the best known way to satisfy the question is using Cargo's CLI, i.e., cargo tree or cargo metadata, in tandem with editing Cargo manifests directly. A Git mirror of Firefox's source code can be found at mozilla/gecko-dev.

A full checkout of gecko-dev fills multiple gigabytes, and is not recommended to make one locally unless you plan on doing work directly on Firefox. However, we can optimize to somewhat less than 1 GiB of storage, and speed up the checkout process by using git sparse-checkout:

git clone --sparse --depth=1 'https://github.com/mozilla/gecko-dev.git'
cd gecko-dev
git sparse-checkout set --no-cone
git sparse-checkout add \
  '**/Cargo.toml' \
  '**/lib.rs' \
  '**/main.rs' \
  '**/src/bin/*.rs' \
  ;

From here, you can invoke Cargo with the --locked flag, i.e:

cargo --locked tree -i itertools
cargo --locked metadata --format-version=1
⚠️ **GitHub.com Fallback** ⚠️