Cargo pulled in the same package twice, as two copies

Cargo pulled in two copies of the same package, due to some patching problem.
The package is in under both its long rev ID and its short rev ID.

At the workspace Cargo.toml file, there's this patch:

[patch.crates-io]
...
rend3-egui = { version = "^0.3.0", git = 'https://github.com/BVE-Reborn/rend3.git', rev = "0e01337" }

Then, in each subproject, there's a line such as:

rend3-egui = { git = 'https://github.com/BVE-Reborn/rend3.git' }

Somehow, though, cargo got confused and created a strange rev. Note the lines

  • source = "git+https://github.com/BVE-Reborn/rend3.git?rev=0e01337#0e01337a2a0261449151b7fce0013d242da0e7f5"
  • source = "git+https://github.com/BVE-Reborn/rend3.git#0e01337a2a0261449151b7fce0013d242da0e7f5"

Those somehow were generated. They refer to the same rev ID, but cargo does not recognize that.

Here's the relevant section of cargo.lock:

[[package]]
name = "rend3-egui"
version = "0.3.0"
source = "git+https://github.com/BVE-Reborn/rend3.git?rev=0e01337#0e01337a2a0261449151b7fce0013d242da0e7f5"
dependencies = [
 "egui 0.24.1",
 "egui-wgpu",
 "glam",
 "rend3 0.3.0 (git+https://github.com/BVE-Reborn/rend3.git?rev=0e01337)",
 "wgpu 0.18.0",
 "wgpu-types 0.18.0",
]

[[package]]
name = "rend3-egui"
version = "0.3.0"
source = "git+https://github.com/BVE-Reborn/rend3.git#0e01337a2a0261449151b7fce0013d242da0e7f5"
dependencies = [
 "egui 0.24.1",
 "egui-wgpu",
 "glam",
 "rend3 0.3.0 (git+https://github.com/BVE-Reborn/rend3.git)",
 "wgpu 0.18.0",
 "wgpu-types 0.18.0",
]

Any reason not to use a workspace dependency? Workspaces - The Cargo Book The patch table is for dependencies of your dependencies that you normally can't specify.

OK, tried that.

[workspace.dependencies]
rend3 = { version = "^0.3.0", git = 'https://github.com/BVE-Reborn/rend3.git', rev = "0e01337" }
rend3-egui = { version = "^0.3.0", git = 'https://github.com/BVE-Reborn/rend3.git', rev = "0e01337" }
rend3-framework = { version = "^0.3.0", git = 'https://github.com/BVE-Reborn/rend3.git', rev = "0e01337" }
rend3-routine = { version = "^0.3.0", git = 'https://github.com/BVE-Reborn/rend3.git', rev = "0e01337" }
libui = { version = "^0.8.0", git = "https://github.com/John-Nagle/ui-mock.git", branch = "gpu-culling" }

Different error:

 cargo build
    Updating crates.io index
error: failed to select a version for `wasm-bindgen`.
    ... required by package `rend3-framework v0.3.0`
    ... which satisfies dependency `rend3-framework = "^0.3.0"` of package `sharpview v0.5.0 (/home/john/projects/sl/SL-test-viewer/sharpview)`
versions that meet the requirements `=0.2.78` are: 0.2.78

all possible versions conflict with previously selected packages.

  previously selected package `wasm-bindgen v0.2.89`
    ... which satisfies dependency `wasm-bindgen = "^0.2.45"` (locked to 0.2.89) of package `winit v0.28.7`
    ... which satisfies dependency `winit = "^0.28"` (locked to 0.28.7) of package `sharpview v0.5.0 (/home/john/projects/sl/SL-test-viewer/sharpview)`

failed to select a version for `wasm-bindgen` which could resolve this conflict

That seems to indicate that cargo, instead of using the current commit ID specified in the override (https://github.com/BVE-Reborn/rend3/blob/84ee5d80af95aa13eca505f0668b9a8bdf58f1e2/rend3-framework/Cargo.toml) went back to Febuary 2022 and an old revision at https://github.com/BVE-Reborn/rend3/blob/84ee5d80af95aa13eca505f0668b9a8bdf58f1e2/rend3-framework/Cargo.toml
to find a Cargo.toml file that wanted `=0.2.78'.

No idea where that came from.

What did I break?

Did you also put workspace = true in your subprojects? Also those two urls you posted are identical.

Oh, sorry. Current URL is https://github.com/BVE-Reborn/rend3/blob/trunk/rend3-framework/Cargo.toml

Did you also put workspace = true in your subprojects?

No, because nothing on

says to do that. I have not seen that syntax before. That can be written in the [lints] section, but that's irrelevant to this problem.

The link I posted has this:

The dependencies table

The workspace.dependencies table is where you define dependencies to be inherited by members of a workspace.

Specifying a workspace dependency is similar to package dependencies except:

  • Dependencies from this table cannot be declared as optional
  • features declared in this table are additive with the features from [dependencies]

You can then inherit the workspace dependency as a package dependency

Example:

# [PROJECT_DIR]/Cargo.toml
[workspace]
members = ["bar"]

[workspace.dependencies]
cc = "1.0.73"
rand = "0.8.5"
regex = { version = "1.6.0", default-features = false, features = ["std"] }
# [PROJECT_DIR]/bar/Cargo.toml
[package]
name = "bar"
version = "0.2.0"

[dependencies]
regex = { workspace = true, features = ["unicode"] }

[build-dependencies]
cc.workspace = true

[dev-dependencies]
rand.workspace = true

For yours, it'll be something like this

[dependencies]
rend3-egui = { workspace = true }

These are other identical ways of writing the above:

[dependencies]
rend3-egui.workspace = true
[dependencies.rend3-egui]
workspace = true
1 Like

OK. Using "workspace = true" in all subprojects fixed the second problem. Now I'm back to the first problem. I'm trying to force ui-mock to use the same version of Rend3 as everything else.

[workspace.dependencies]
# 0e01337 - GPU culling
rend3 = { version = "^0.3.0", git = 'https://github.com/BVE-Reborn/rend3.git', rev = "0e01337" }
rend3-egui = { version = "^0.3.0", git = 'https://github.com/BVE-Reborn/rend3.git', rev = "0e01337" }
rend3-framework = { version = "^0.3.0", git = 'https://github.com/BVE-Reborn/rend3.git', rev = "0e01337" }
rend3-routine = { version = "^0.3.0", git = 'https://github.com/BVE-Reborn/rend3.git', rev = "0e01337" }
libui = { version = "^0.8.0", git = "https://github.com/John-Nagle/ui-mock.git", branch = "gpu-culling" }

[patch."https://github.com/John-Nagle/ui-mock.git"]
rend3 = { version = "^0.3.0", git = 'https://github.com/BVE-Reborn/rend3.git', rev = "0e01337" }
rend3-egui = { version = "^0.3.0", git = 'https://github.com/BVE-Reborn/rend3.git', rev = "0e01337" }
rend3-framework = { version = "^0.3.0", git = 'https://github.com/BVE-Reborn/rend3.git', rev = "0e01337" }
rend3-routine = { version = "^0.3.0", git = 'https://github.com/BVE-Reborn/rend3.git', rev = "0e01337" }

I get "note: perhaps two different versions of crate rend3 are being used?" The "patch" lines aren't overriding ui-mock's internal selection. Doesn't matter whether I include that section or not.

This patch will patch dependencies which have https://github.com/John-Nagle/ui-mock.git as a source. Your https://github.com/John-Nagle/ui-mock/blob/main/Cargo.toml is taking deps from the default source, crates.io, so you need a [patch.crates-io] to patch it.

(I think you should get a warning like "patch not used in dependency graph", but I'm not sure)

1 Like

No "patch not used in dependency graph" warning.

Had to go over to ui-mock and make it explicitly use the desired version of Rend3, rather than trying to patch it.

The real problem is that I'm trying to use crates that have had major changes while keeping the same version number. Cargo can just barely handle that. Versioned crates work much better.

Unfortunately, Cargo has no unification of git dependencies. If they're specified differently, even if it's essentially the same thing written in a slightly different way, they're treated as completely unrelated packages. That's because Cargo makes a fake URL for your git parameters, and each URL is treated as a different one.


When you're applying a patch, the version must match. You can't replace a dependency with a "wrong" version". You can't use patch if you have multiple different versions to patch. Instead, you'll have to patch every parent crate requiring these dependencies and make them require the same version.

Right. I get that now. I was hoping that all the Cargo patching features would get me through this, but no such luck.