Cargo: Automatically enable required-features when running an example

Created on 26 Oct 2017  路  8Comments  路  Source: rust-lang/cargo

If I have a crate like:

[package]
name = "foo"

[features]
myfeature = []
another = []

[[example]]
name = "myexample"
required-features = ["myfeature", "another"]

It would be awesome if cargo run --example myexample automatically enabled the myfeature feature for me, rather than producing an error message like it does today. There is no situation where I can do anything useful without padding the additional --features myfeature flag.

This is the current message:

error: target `myexample` requires the features: `myfeature`, `another`
Consider enabling them by passing e.g. `--features="myfeature another"`
A-features A-required-features C-feature-request

Most helpful comment

Any updates on this?

All 8 comments

Is there a possibility to alter this issue to also include binaries? I currently have:

[package]
name = "lambdapi"

[features]
cli = ["rustyline", "structopt"]

[[bin]]
name = "lambdapi"
required-features = ["cli"]

[dependencies]
rustyline = { version = "1.0.0", optional = true }
structopt = { version = "0.2.2", optional = true }

At the moment running: cargo run gives:

error: target `lambdapi` requires the features: `cli`
Consider enabling them by passing e.g. `--features="cli"`

Instead I have to run: cargo run --features=cli, which feels kinda clunky. It seems weird from a user perspective that cargo knows it requires them, but doesn't fill them in for you.

Joining the request - we are hitting this in three-rs with "gltf-loader" feature.

@Gankro is looking for mentors, cc @rust-lang/cargo

So, unfortunately this, while it sounds like an E-should-not-be-that-hard bug, is actually pretty tricky to fix properly! However we probably could get a 80% working solution without too too much effort.

The error originates from this function, whose job is to determine which targets should be compiled, based on the CLI flags (filter and packages). Unfortunately, it is too late to enable additional features by this time. This is because Cargo selects features early in the build cycle, during initial dependency resolution, so resolve: &Resolve, argument holds info not only about dependencies between packages, but about activated features as well.

The proper solution here I believe is to remove features from resolve, and instead do feature selection later, exactly in the generate_targets function, which should fix https://github.com/rust-lang/cargo/issues/4463, a number of similar bugs, and quite probably break some builds which relay on the current behavior.

The 80% solution would be to enable required features before we construct resolve. This happens over here:

https://github.com/rust-lang/cargo/blob/420f9ec576f93f35366a610a4be3a805e9021f7c/src/cargo/ops/cargo_compile.rs#L353-L359

(and we get there from this code, specific to cargo run)

I think, for cargo run specifically, we can push missing features to features vec. Note, however, that this features apply only to the "current" package, that is, package at the working directory. So, the 80% fix would be

  • if we are in cargo run
  • and the user hasn't requested any features explicitly (no --feature, --all-features, --no-deafult-features arguments)
  • and the user is running binary from the current package (that is, not cargo run -p foo --bin bar)
  • then we add all required features.

I think that with some amount of legwork we could get rid of current package restriction as well, but that would make certain cargo run invocations enable feature configurations, which are impossible with explicit --feature flags, and that makes me feel uneasy.

If we don't want to fix current package limitation, then, implementation wise, I think we should express this as desugaring of cli arguments, by modifying options.features here, and that should tickle down to that resolve construction code.

Any updates on this?

This would also be nice for crates which offer optional binaries, where there are features that don't have to be there by default for the library but are required for binaries.

Just wanted to point that the feature proposal from https://github.com/rust-lang/rfcs/pull/2887 will fix this if implemented.

I haven't seen it mentioned here, but the current behaviour is anti-useful:

$ cargo run --example widget_gallery
error: target `widget_gallery` in package `druid` requires the features: `svg`, `im`, `image`, `png`
Consider enabling them by passing, e.g., `--features="svg im image png"`
$ cargo run --example widget_gallery --features="svg im image png"
error: --features is not allowed in the root of a virtual workspace
note: while this was previously accepted, it didn't actually do anything
$ cargo --version
cargo 1.47.0
Was this page helpful?
0 / 5 - 0 ratings