Describe the problem you are trying to solve
When building libraries that have backends in them using --features flag in combination with the feature dependencies, it would be very useful to have a "no feature selected" configuration option so a "default" backend can be chosen.
Describe the solution you'd like
Either something like
[features]
backend1 = ["some_dep"]
backend2 = ["some_dep2"]
default_features = ["backend2"]
If the user just does cargo build or doesn't specify a feature list in their dependency definition for this crate they will get backend2 selected by default as if they did --features backend2. Same would happen for a project using this crate and not specifying features = in their dependency definition.
The other way of doing this could be to provide a #[cfg(nofeatures)] in case no features were chosen so that it could be used to provide a default in code.
A more thorough design might be desirable however. Possibly with groups of features so that a default is tied only to "lack" of some features, but not all.
For example consider a project providing backend1, backend2, non_backend_feature as features. If non_backend_feature is chosen it shouldn't override the default in this case for the backend choice.
Having groups of features could make this possible.
Notes
This already exists, and is called default: https://doc.rust-lang.org/cargo/reference/manifest.html#the-features-section
Indeed. Going to assume you just missed this part of the docs, @almindor. Let me know if you meant something else.
@almindor I wouldn't call it default_features since default already exists. As you can already see, this name is confusing.
@sfackler No, if I got it right, he want's something different.
The thing is, we want some features, that are only used, when no features are specified.
In this example, when just writing --features "backend1" "backend2" won't be used.
This would make it easier to switch backends.
For example the default backend for some graphics application would be "vulkan", but for some older platforms or mac, that don't support, you choose a different backend, which will just disable the default feature "vulkan" and only load the dependencies for "opengl" or "metal" or whatever.
Another Idea I have is some other kind of features (let's call them backends), which just work like features, but you are only allowed to select exactly one, like this:
[backends]
backend1 = ["some_dep"]
backend2 = ["some_dep2"]
default = ["backend2"]
If your apllication supports multiple kinds of backends, it could look like this:
[graphics.backends]
vulkan = ["some_dep"]
metal = ["some_dep2"]
default = "vulkan" #default doesn't require a list, because only one is allowed
[audio.backends]
alsa = []
These features could still be specified by using "--features", but in case no default is specified, cargo will not even start compiliation.
Or some more general way: add a way to make specific features incompatible.
As @porky11 said this is something else than you think. It's a way to have an feature pre-selected if a user doesn't specify one but only if they don't specify one. Default does not get "deselected" when you select a specific feature as far as I know.
@dwijnand sorry forgot to flag you, see above. The issue is different than you think
I see, thanks for the detail.
I have the same requirement and I think these can be considered as enum feature flags, where one needs to select one feature flag of a group, and if no one is selected, a default one should be used.
Most helpful comment
I have the same requirement and I think these can be considered as enum feature flags, where one needs to select one feature flag of a group, and if no one is selected, a default one should be used.