Search code examples
rustrust-cargo

How can I exclude a crate from compilation when a feature is disabled?


I have a Rust project that follows a structure:

- main_crate (features = "x")
  - driver_crate (features = "x")
    - x_crate
    ...
  ...

In my main_crate, I have a feature flag x that I enable by default which is propagated to the driver_crate via the following setup in main_crate/Cargo.toml:

[features]
x = ["driver-crate/x"]

# default = ["x"]

The driver_crate/Cargo.toml specifies the x dependency as optional in the following way:

[dependencies]
x-crate = { path = "../x-crate", optional = true }

[features]
x = ["dep:x-crate"]

Suppose that I run cargo build --no-default-features, my expectation is that now that x is no longer enabled by default, Cargo should now treat the x dependency as false and hence not even attempt to compile it as part of the project. Instead, cargo still adds x_crate as part of the compilation process.

Furthermore, I verified that "x" crate is not in the "dependency" tree when I do the following command:

cargo tree -p main_crate | grep "x_crate"

It is however present when I specifically enable x:

cargo tree -p main_crate -F "x" | grep "x_crate"
│   │   ├── x_crate v0.1.0 (/src/x_crate)

Is there a way to ensure that x_crate is not compiled at all when feature x is not specified?

Update: I realised why it's included in the compilation. My project is using a virtual manifest that specifies that the members of the workspace are src/* which automatically includes x:

[workspace]
members = [
  "src/*",

How can I dynamically include/exclude x_crate as a dependency when I specify x feature flag to the workspace?


Solution

  • The crate is being compiled because in a workspace, Cargo by default builds all packages.

    You can build only a specific package (and its dependencies) with cargo build --package <package> (cargo build -p <package>), or set a default package for all cargo builds via workspace.default-members.