I'm building a crate that depends on a local crate twice- once directly and once transitively via another local crate. When I build with wasm-pack, I get an error from Cargo about a package collision in the lockfile. This error does not appear when building with Cargo directly.
The build should succeed.
I've reduced the problem to this directory structure:
wasm-bug/
main/
Cargo.toml
src/lib.rs
dep_a/
Cargo.toml
src/lib.rs
dep_b/
Cargo.toml
src/lib.rs
Here is main/Cargo.toml:
[package]
name = "wasm-bug"
version = "0.1.0"
authors = ["Russell Johnston <[email protected]>"]
[lib]
crate-type = ["cdylib"]
[dependencies]
wasm-bindgen = "0.2"
dep_a = { path = "../dep_a" }
dep_b = { path = "../dep_b" }
Here is dep_a/Cargo.toml:
[package]
name = "dep_a"
version = "0.1.0"
authors = ["Russell Johnston <[email protected]>"]
[dependencies]
dep_b = { path = "../dep_b" }
Here is dep_b/Cargo.toml:
[package]
name = "dep_b"
version = "0.1.0"
authors = ["Russell Johnston <[email protected]>"]
[dependencies]
The command wasm-pack build (from the wasm-bug/main/ directory) produces this error from Cargo:
error: package collision in the lockfile: packages dep_b v0.1.0 (C:\Users\Russell\Desktop\wasm-bug\main\../dep_b) and dep_b v0.1.0 (C:\Users\Russell\Desktop\wasm-bug\dep_b) are different, but only one can be written to lockfile unambiguously
When I run Cargo directly with cargo build --lib --release --target wasm32-unknown-unknown (taken from wasm-pack.log) the build succeeds.
The bug happens whether or not the crates are part of a workspace. (My original use case has them in a workspace; I removed it as part of the reduced repro above.)
I've also tried the workaround in https://github.com/rustwasm/wasm-pack/issues/380#issuecomment-425222252, since it seemed potentially related, but it did not change things.
wasm-pack version: 0.5.1
cargo version: 1.31.0-nightly (5dbac9888 2018-10-08)
I'm also on Windows, which may be relevant since I haven't tested this on Linux.
I had the same problem so i went and investigated.
The underlying issue is the same as https://github.com/rustwasm/wasm-pack/issues/380 and it will be fixed once PR https://github.com/rustwasm/wasm-pack/pull/389 lands
Thanks! I can now also reproduce this with just Cargo, via cargo build --manifest-path \\?\C:\Users\Russell\Desktop\wasm-bug\main\Cargo.toml. I'm not sure if this is really a wasm-pack bug at this point, so I filed https://github.com/rust-lang/cargo/issues/6198.
Reporting back from the Cargo issue: Cargo currently doesn't really handle, or even have a way to handle, \\?\-based paths, which is what fs::canonicalize produces. It could be fixed but it's a lot of work.
However, we never really wanted to be doing that anyway- wasm-pack is just using canonicalize to get an absolute path, and doesn't need a \\?\-based one. According to @retep998 and https://github.com/rust-lang/cargo/issues/6198#issuecomment-433156505, the best way to do that on windows is not canonicalization, but GetFullPathNameW.
Unfortunately std does not expose that function (honestly it might have been a good choice for fs::canonicalize at one point), but wasm-pack could use it via winapi. That's probably a cleaner solution than #389.
i believe this should be fixed on master now? i'll be doing a release this week- but if you could check if you still see this on master, that'd be great! thanks for the detailed bug report and sorry for the delay in responding! i appreciate your patience
Yes, I can confirm this is fixed on master. Thanks!
Most helpful comment
Reporting back from the Cargo issue: Cargo currently doesn't really handle, or even have a way to handle,
\\?\-based paths, which is whatfs::canonicalizeproduces. It could be fixed but it's a lot of work.However, we never really wanted to be doing that anyway-
wasm-packis just usingcanonicalizeto get an absolute path, and doesn't need a\\?\-based one. According to @retep998 and https://github.com/rust-lang/cargo/issues/6198#issuecomment-433156505, the best way to do that on windows is not canonicalization, butGetFullPathNameW.Unfortunately
stddoes not expose that function (honestly it might have been a good choice forfs::canonicalizeat one point), butwasm-packcould use it viawinapi. That's probably a cleaner solution than #389.