Cargo: Enabling a feature on a dependency also activates the optional dependency

Created on 18 Aug 2019  路  2Comments  路  Source: rust-lang/cargo

Apologies if the problem is filed before. I scanned through the issues and found a whole lot of similar but not quite exactly that. Please feel free to close as a dupe if I missed it.

Problem
Consider the following configuration of an optional dependency "bar":

[features]
"foo" = ["bar/foo"]
[dependencies]
"bar" = { version = "0.1", optional = true }

Now, suppose we are doing cargo check --features "foo".
Expected result: project builds without "bar" enabled
Actual result: project builds with "bar" enabled

Here is a more concrete example from https://github.com/gfx-rs/wgpu/pull/290:

[features]
window-winit = ["winit", "gfx-backend-empty/winit", "gfx-backend-vulkan/winit", "gfx-backend-dx11/winit", "gfx-backend-dx12/winit", "gfx-backend-metal/winit", "gfx-backend-gl/glutin"]

[dependencies]
gfx-backend-empty = { version = "0.3.0" }
gfx-backend-vulkan = { version = "0.3.0", features = ["x11"], optional = true }
gfx-backend-dx11 = { version = "0.3.0", optional = true }
gfx-backend-dx12 = { version = "0.3.0", optional = true }
gfx-backend-metal = { version = "0.3.0", optional = true }
gfx-backend-gl = { version = "0.3.0", optional = true }

We have quite a few dependencies that have this optional feature "winit". We want to be able to build it as: cargo build --features window-winit,gfx-backend-dx12, expecting that the DX12 backend is enabled, and it has the "winit" feature enabled.
What happens instead is that every optional dependency listed in "window-winit" gets enabled.

Is this by design? Is there a way to express what we want through the config?

Notes

This is a very annoying issue in gfx-rs ecosystem. It affects Amethyst, wgpu-rs and potentially other projects that want certain properties (such as "winit" or "serde" dependencies) of the backends to be configurable.

Output of cargo version:

cargo 1.36.0 (c4fcfb725 2019-05-15)

C-bug

Most helpful comment

Thanks! I think this is essentially #3494 (and #6658 and #5023), so I'm going to close in favor of that.

All 2 comments

A few months ago I was affected by this issue as well. The workaround I applied was to split up the two features: https://github.com/contain-rs/bit-vec/pull/60/files

Obviously this workaround does not scale to your use case.

It would be a breaking change if now suddenly "foo" = ["bar/foo"] would mean that bar is not enabled. So I guess new syntax has to be introduced. Strawman proposal: "foo" = ["?bar/foo"].

Thanks! I think this is essentially #3494 (and #6658 and #5023), so I'm going to close in favor of that.

Was this page helpful?
0 / 5 - 0 ratings