cargo-hack icon indicating copy to clipboard operation
cargo-hack copied to clipboard

express mutually exclusive features

Open robjtede opened this issue 3 years ago • 4 comments

I don't really understand what --group-features is doing just from the readme or help output so it's possible I'm using it wrong and that this is possible already.

I want to provide an optional TLS backend openssl or rustls but they emit conflicting code so using --feature-powerset is not working out yet.

TIA

robjtede avatar Oct 20 '21 15:10 robjtede

I don't think there is currently a way to do this with a single command. (--group-features treats the specified features as if it were a single feature.)

If you are okay with splitting it into multiple commands, I think you can express this by combining --skip(--exclude-features) and --features.

# All combinations that contain openssl and do not contain rustls.
cargo hack build --feature-powerset --features openssl --skip rustls
# All combinations that contain rustls and do not openssl.
cargo hack build --feature-powerset --features rustls --skip openssl
# All combinations that do not contain both openssl and rustls.
cargo hack build --feature-powerset --skip openssl,rustls

taiki-e avatar Oct 20 '21 15:10 taiki-e

I'm okay with adding a flag for such use-case, but given that cargo itself does not recommend the use of mutually exclusive features, we will probably need documentation to warn about it.

https://doc.rust-lang.org/cargo/reference/features.html#mutually-exclusive-features

There are rare cases where features may be mutually incompatible with one another. This should be avoided if at all possible, because it requires coordinating all uses of the package in the dependency graph to cooperate to avoid enabling them together. If it is not possible, consider adding a compile error to detect this scenario.

Instead of using mutually exclusive features, consider some other options:

  • Split the functionality into separate packages.
  • When there is a conflict, choose one feature over another. The cfg-if package can help with writing more complex cfg expressions.
  • Architect the code to allow the features to be enabled concurrently, and use runtime options to control which is used. For example, use a config file, command-line argument, or environment variable to choose which behavior to enable.

taiki-e avatar Oct 20 '21 15:10 taiki-e

https://github.com/taiki-e/cargo-hack/issues/132#issuecomment-947800980

If it is not possible, consider adding a compile error to detect this scenario.

Btw, #115 is a feature request to check that a proper compilation error occurs in such cases.

taiki-e avatar Oct 20 '21 15:10 taiki-e

cargo itself does not recommend the use of mutually exclusive features

Yeah... it's a tricky one.

If you are okay with splitting it into multiple commands

This is a perfectly reasonable way to handle it with just one set of mutually exclusive features.

robjtede avatar Oct 20 '21 15:10 robjtede