Enable features for a binary

Problem description

  • I have a crate foo that has a feature frob, which doesn't do anything but is supposed to activate a feature of the same name in a dependency bar which I also control.
  • In foo, I have a [lib] and a [[bin]] entry in my Cargo.toml. I also have integration tests in foo.

I want the feature frob to be disabled in the lib (the default), but enabled by default in the bin and the integration tests. This seems not to be possible.

What I've tried

dev-dependencies

Put something like this in my foo/Cargo.toml:

[dependencies]
bar = {path = "../bar"}
[dev-dependencies]
bar = {path = "../bar", features=["bar/frob"]}

This activates the features in the tests, but also in the lib! Seems to be a bug, which has been noticed before: https://github.com/rust-lang/cargo/issues/2911#issuecomment-771895047

required-features

Add this to my [[bin]] section:

required-features = ["frob"]

It seems to have no effect. Probably also expected: https://github.com/rust-lang/cargo/issues/2911#issuecomment-406278859

--features frob

Right now, I manually add --features frob whenever I build my bins. This is error-prone, since when I forget it, the feature is simply not activated, causing (in my case) a silent error.

You just need to do:

# Your Foo package
package = "foo"

[features]
# No default features for crate foo
default = []
# A frob feature that enables the frob feature
# of the bar crate that you depend on
frob = ["bar/frob"]

[dependencies]
bar = { path = "../bar" }

Edit: Oh, wait, I think I misunderstood your meaning. Let me think...


Edit2: I'm not sure if there is a better way to do this, but you could create a separate crate for the binary target, such as foo-cli. That would have it's own Cargo.toml file and it would require your foo library and specify that it needs the frob feature.

Let me know if you need more thorough example of that.

1 Like

A separate crate is a possible workaround, yes. But also the last resort.

I don't think it's possible, but maybe you can make it less error prone by adding another feature bin-disable-frob and add below lines to your main.rs.

#[cfg(all(not(feature = "frob"), not(feature = "bin-disable-frob")))]
compile_error!("To build binary without `frob` feature, enable `bin-disable-frob` feature instead");

Feature flags are meant to be driven by the end user so your binary and integration tests can't turn them on for themselves. You'd need to change how you build and run tests.

# build the library and test it
$ cargo build --no-default-features --lib
$ cargo test --no-default-features --lib

# build the binary
$ cargo build --bin --features frob

# run integration tests
$ cargo test --tests --features frob

The required-features flag is meant to let you say "if feature frob is enabled, build this binary".

https://doc.rust-lang.org/cargo/reference/cargo-targets.html#the-required-features-field

2 Likes

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.