rust-lang / rust-lang/cargo

Mutually exclusive features

Open
#2,980 39 comments 98 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

A-features C-enhancement S-needs-rfc
Dominant language
Rust
Stars
15.5k
Forks
3k
Avg merge
23h 30m
Merged PRs (30d)
51

Description

In Windows API there is the notion of a family and partitions. Your choice of family is basically which platform you are targeting and there is a choice between WINAPI_FAMILY_DESKTOP_APP WINAPI_FAMILY_PC_APP WINAPI_FAMILY_PHONE_APP WINAPI_FAMILY_SYSTEM and WINAPI_FAMILY_SERVER. Your choice of family in turn enables certain partitions which enable access to certain functionality. At the moment I cannot use cargo features for this because they are not mutually exclusive, so two downstream dependencies could specify different families which is completely wrong. Even if I use a build script to ensure only one such feature is selected, it would be a nightmare to ensure that every single downstream dependency chooses the same family, threading the choice of family feature through long chains of transitive dependencies that shouldn't have to care about that choice.

What I think would work well here is some sort of feature selection that has to choose exactly one option from a closed set, and that choice is controlled by the root crate. All dependencies that are affected by that choice will then need some way to be informed of the choice so they can adjust which functionality to use depending on that choice.

At the moment the only workaround I see is for the user to pass an environment variable while building the project so winapi's build script can read that to choose the family followed by emitting key=value stuff which downstream dependencies can read via build scripts through the DEP_WINAPI_key=value environment variables to emit cfgs to control their own code.

Also, this can also apply to other choices, such as which version of Windows you want to target, newer versions have more functionality that dependencies might want to be able to take advantage of, but the user might also want them to target an older version instead so it can run on more systems.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reviewing Cargo's feature resolution and build-script behavior described in the issue, focusing on how choices from the root crate could affect dependencies. Define how exactly one option would be selected and propagated through dependency chains, including Windows family and version choices; the work is done when the behavior and scope are specified clearly enough to implement and test.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
build-system, tooling
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
30/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.