Cargo build failing when combining two dependencies

I'm having troubles building a library and tracking the bug (reason) of why it's failing.

I reduced the problem to the following. Let's say you have the following Cargo.toml file.

[package]
name = "buildfail"
version = "0.1.0"
authors = ["Abid Omar <contact@omarabid.com>"]
edition = "2018"

[lib]
crate-type = ["cdylib", "rlib"]


[dependencies]
wasm-service = { version = "0.5", features=["std"] }
juniper = "0.14"

You run cargo build for wasm. It compiles.

cargo build --target wasm32-unknown-unknown

Now, if you change the version of Juniper to "0.15", the build fails. This is the error message.

error: target is not supported, for more information see: https://docs.rs/getrandom/#unsupported-targets
   --> /home/xxxxx/.cargo/registry/src/github.com-1ecc6299db9ec823/getrandom-0.2.2/src/lib.rs:213:9
    |
213 | /         compile_error!("target is not supported, for more information see: \
214 | |                         https://docs.rs/getrandom/#unsupported-targets");
    | |_________________________________________________________________________^

error[E0433]: failed to resolve: use of undeclared crate or module `imp`
   --> /home/xxxxx/.cargo/registry/src/github.com-1ecc6299db9ec823/getrandom-0.2.2/src/lib.rs:235:5
    |
235 |     imp::getrandom_inner(dest)
    |     ^^^ use of undeclared crate or module `imp`

error: aborting due to 2 previous errors

The perplexing thing is that juniper 0.15 and wasm-service 0.5 both compiles just fine on their own. However, adding them together in the same file fails the compilation. What is the reason for that?

If multiple crates in your dependency graph share a common dependency, Cargo builds that dependency with the union of all features activated by all the crates. In the current version of Cargo, it even unifies features from crates that are not used on the current platform.

This seems to be the cause of your problem, since wasm-service and juniper 0.15 both depend indirectly on getrandom 0.2, but wasm-service depends on it via wrangler, which is used by kv-assets only on non-WASM targets.

Starting in Rust 1.51 (which is currently available on the beta channel, and will be released to the stable channel on March 25th), you can activate the new feature resolver to fix this problem. In a future edition of Rust, the new resolver will be enabled by default.

1 Like

Related question: can you figure out, in a specific build, what crate was built with what features other than manually?

I only know to grep through the output of cargo clean; cargo build -v.

The features also seem to be recorded in the JSON files in e.g. target/debug/.fingerprint, though if you don't do a clean build, you might need to sort through multiple files for a given crate.

cargo tree -e features
2 Likes

Thanks. I'm trying to stay on stable, so forked the dependency and made some changes to it. Can you share the commands you used to determine the particular dependency/feature. There are dozens (hundreds?) so going through them manually is not possible.

To see which crates used getrandom, I ran the following command:

cargo tree -i getrandom:0.2.2

As @kornel notes above, you can add the -e features option to add information about features to the cargo tree output.

Fortunately, the new feature resolver will be available on stable in just about two weeks.

1 Like

New Resolver is here now :slight_smile: