Cargo run with different feature flags does not taken effect

I have a cargo workspace with the below folder structure

.
├── Cargo.lock
├── Cargo.toml
├── myfeature
│   ├── Cargo.toml
│   └── src
│       └── lib.rs
└── server
    ├── Cargo.toml
    └── src
        └── main.rs
---
# Workspace Cargo.toml
[workspace]
members = ["myfeature", "server"]

In myfeature Cargo.toml, I have

[package]
name = "myfeature"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[features]
default =["cde"]
abc=[]
cde=[]
[dependencies]

and the lib.rs is just

#[cfg(not(feature="abc"))]
pub fn add(left: usize, right: usize) -> usize {
    println!("not abc");
    left + right
}
#[cfg(all(feature="abc"))]
pub fn add(left: usize, right: usize) -> usize {
    println!("abc");
    left + right
}

In the server crate, I have Cargo.toml as

[package]
name = "server"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[features]
abc=["myfeature/abc"]
cde=["myfeature/cde"]

[dependencies]
myfeature = {path = "../myfeature", features = ["abc", "cde"], version = "*", optional = true}

and the main.rs is simply

fn main() {
    myfeature::add(1,2);    
}

I was trying to run cargo run --bin server --features="cde" and hoping to see not abc got printed, however, I still see abc got printed, which means my binary is still compiled with the feature="abc"

What am I missing here? Is there any way I can make different binaries with different features? Thanks in advance!

^ You are enabling both features, abc and cde here, but the whole dependency is optional.
With features="cde" on the server package you enable the optional depedency. Cargo then merges the enabled features from the list of features in the dependency entry and the one you enable using the myfeature/cde syntax.
Thus ["abc", "cde"] | ["cde"] = ["abc", "cde"].

If you leave out the features = ... part it works.

1 Like

Thank you @jer for your answer. Leaving out the features=... does work

#server Cargo.toml

[package]
name = "server"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
# [features]
# abc=["myfeature/abc"]
# cde=["myfeature/cde"]

[dependencies]
myfeature = {path = "../myfeature", version = "*", optional = true}

In addition to that, I was hoping to build two binaries with cargo build, one binary with one feature. My server cargo.toml is like this

[package]
name = "server"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
# [features]
# abc=["myfeature/abc"]
# cde=["myfeature/cde"]
[[bin]]
name="abc"
path="src/main.rs"
required-features=["myfeature/abc"]

[[bin]]
name="cde"
path="src/main.rs"
required-features=["myfeature/cde"]

[dependencies]
myfeature = {path = "../myfeature", version = "*", optional = true}

and I ran cargo build --all-features. The problem is both abc and cde binary is build with the same feature flag ('myfeature/abc"). Is there any ways to build this two binaries with different feature flag in one run?