Cargo: Disable a dependency for a given feature while using `--offline`

Hello,
I am puzzled by some Cargo behaviour. I can't figure out if it's a feature or a bug.

I have a Cargo.toml like this:

[package]
name = "cargo_testcase"
version = "1.0.0"
edition = "2018"

[dependencies]
jack = { version = "^0.8.1", optional = true }

[features]
default = ["testcase"]
testcase = ["jack"]

[[bin]]
name = "cargo_testcase"
required-features = ["testcase"]

My understanding of what this means:

  • By default, build cargo_testcase binary, which requires dependency jack
  • If cargo_testcase feature is disabled, build nothing.

This example represents one component in a larger workspace, hence why I want the ability to disable it completely.

I was trying to build my project on a train with no internet access, and I found that disabling the feature didn't disable the dependency on jack:

> cargo build --offline --no-default-features
error: failed to select a version for the requirement `jack = "^0.8.1"`
candidate versions found which didn't match: 0.7.1, 0.7.0, 0.6.6, ...
location searched: crates.io index
required by package `cargo_testcase v1.0.0 (/home/sam/cargo-feature-testcase)`
As a reminder, you're using offline mode (--offline) which can sometimes cause surprising resolution failures, if this error is too confusing you may wish to retry without the offline flag.

Now I am at home and have internet access, so I can run Cargo without --offline:

> cargo build --no-default-features
    Updating crates.io index
    Finished dev [unoptimized + debuginfo] target(s) in 1m 07s

It seems to have now done what I expected - built nothing because I disabled the feature.

Is this a bug in --offline or am I misunderstanding something about how it works? I have Cargo version 1.56.0.

Your local checkout of the registry was outdated such that it only contained versions of jack up to 0.7.1 and not 0.8.0 as you specified. Due to --offline it doesn't update the local checkout and thus can't find 0.8.0, leading to an error.

The fact that jack is only an optional dependency doesn't matter for the dependency resolution, it still needs to resolve the dependency as it or one of it's dependencies may for example require a transitive dependency to be a newer version. Cargo will in that case force said dependency to the newer version. All dependencies must be resolved before building.

Cargo doesn't need to download the actual package for jack 0.8.0, so if the registry was new enough to include it, it would work when you don't enable the dependency, even if it isn't downloaded yet.

2 Likes

Thanks for the explanation!

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.