Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feature to env var mapping is not unique #3702

Closed
durka opened this issue Feb 14, 2017 · 7 comments · Fixed by #14902
Closed

feature to env var mapping is not unique #3702

durka opened this issue Feb 14, 2017 · 7 comments · Fixed by #14902
Labels
A-build-scripts Area: build.rs scripts A-features Area: features — conditional compilation C-feature-request Category: proposal for a feature. Before PR, ping rust-lang/cargo if this is not `Feature accepted` S-needs-design Status: Needs someone to work further on the design for the feature or fix. NOT YET accepted.

Comments

@durka
Copy link
Contributor

durka commented Feb 14, 2017

Build scripts receive information about activated features as environment variables CARGO_FEATURE_$name, where $name is the feature name uppercased and with dashes converted to underscores.

However, feature names are allowed to contain underscores, so this transformation can create collisions. Example:

  • Cargo.toml
    [package]
    name = "tester"
    version = "0.1.0"
    
    build = "build.rs"
    
    [features]
    foo-bar = []
    foo_bar = []
  • build.rs
    use std::env;
    
    fn main() {
        for (k, v) in env::vars() {
            if k.starts_with("CARGO_FEATURE") {
                println!("{} => {}", k, v);
            }
        }
        panic!(); // so cargo prints the output
    }
  • cargo build --features "foo_bar foo-bar"
    --- stdout
    CARGO_FEATURE_FOO_BAR => 1
    
    --- stderr
    thread 'main' panicked at 'explicit panic', build.rs:9
    note: Run with `RUST_BACKTRACE=1` for a backtrace.
    
@alexcrichton
Copy link
Member

Out of curiosity, was this causing a problem in practice? We could perhaps set both in the case of a - name, but it may also just be best to not recommend naming features as such.

@durka
Copy link
Contributor Author

durka commented Feb 15, 2017 via email

@alexcrichton
Copy link
Member

Yeah that's true and we could handle the case you mentioned in theory by listing everything to the right as well. Should be backwards compatible as well!

@durka
Copy link
Contributor Author

durka commented Feb 15, 2017 via email

@alexcrichton alexcrichton added the A-features Area: features — conditional compilation label Jun 22, 2017
@ehuss ehuss added the A-build-scripts Area: build.rs scripts label Nov 18, 2018
@dwijnand
Copy link
Member

Do we care to support the use case foreman has? Being able to map back from env var to feature name?

If yes, we should decide on which solution to use.
If not, we should close this feature request.

@dwijnand dwijnand added the C-feature-request Category: proposal for a feature. Before PR, ping rust-lang/cargo if this is not `Feature accepted` label Feb 13, 2019
@epage
Copy link
Contributor

epage commented Oct 11, 2023

The case where I would find this helpful is I have tests that compile/run examples and need to pass along feature flags. Maintaining that manually is easy to mess up.

@epage epage added the S-needs-design Status: Needs someone to work further on the design for the feature or fix. NOT YET accepted. label Oct 11, 2023
@wmmc88
Copy link

wmmc88 commented Apr 11, 2024

I have a build script that runs cargo_metadata::MetadataCommand, and would like to forward the same features that the crate enabled. Because of this lossy conversion, the best I can do is gather a list of all the env_vars that start with CARGO_FEATURE_, and try to programmatically match them to the features in the crate (requiring an extra cargo metadata invocation).

Given the backwards-compat issue listed here, I wonder if maybe this could be solved with a new env var that lists all the features? Something like CARGO_CFG_TARGET_FEATURE but for cargo features. Maybe add a CARGO_FEATURES?

epage added a commit to epage/cargo that referenced this issue Dec 6, 2024
This may look redundant with `CARGO_FEATURE_<CASE_CONVERTED_NAME>=1`
except that doesn't provide a lossless way of getting the names, e.g. for
forwarding for child builds like tests that need to build examples.

This also makes things more consistent as users
conditionalize on features through `cfg` and this even fits with what
the `CARGO_CFG_` docs say:

> For each configuration option of the package being built, this
> environment variable will contain the value of the configuration, where
> <cfg> is the name of the configuration uppercased and having -
> translated to _. Boolean configurations are present if they are set, and
> not present otherwise. Configurations with multiple values are joined to
> a single variable with the values delimited by ,. This includes values
> built-in to the compiler (which can be seen with rustc --print=cfg) and
> values set by build scripts and extra flags passed to rustc (such as
> those defined in RUSTFLAGS). Some examples of what these variables are: 

Fixes rust-lang#3702
epage added a commit to epage/cargo that referenced this issue Dec 6, 2024
This may look redundant with `CARGO_FEATURE_<CASE_CONVERTED_NAME>=1`
except that doesn't provide a lossless way of getting the names, e.g. for
forwarding for child builds like tests that need to build examples.

This also makes things more consistent as users
conditionalize on features through `cfg` and this even fits with what
the `CARGO_CFG_` docs say:

> For each configuration option of the package being built, this
> environment variable will contain the value of the configuration, where
> <cfg> is the name of the configuration uppercased and having -
> translated to _. Boolean configurations are present if they are set, and
> not present otherwise. Configurations with multiple values are joined to
> a single variable with the values delimited by ,. This includes values
> built-in to the compiler (which can be seen with rustc --print=cfg) and
> values set by build scripts and extra flags passed to rustc (such as
> those defined in RUSTFLAGS). Some examples of what these variables are: 

Fixes rust-lang#3702
epage added a commit to epage/cargo that referenced this issue Dec 6, 2024
This may look redundant with `CARGO_FEATURE_<CASE_CONVERTED_NAME>=1`
except that doesn't provide a lossless way of getting the names, e.g. for
forwarding for child builds like tests that need to build examples.

This also makes things more consistent as users
conditionalize on features through `cfg` and this even fits with what
the `CARGO_CFG_` docs say:

> For each configuration option of the package being built, this
> environment variable will contain the value of the configuration, where
> <cfg> is the name of the configuration uppercased and having -
> translated to _. Boolean configurations are present if they are set, and
> not present otherwise. Configurations with multiple values are joined to
> a single variable with the values delimited by ,. This includes values
> built-in to the compiler (which can be seen with rustc --print=cfg) and
> values set by build scripts and extra flags passed to rustc (such as
> those defined in RUSTFLAGS). Some examples of what these variables are: 

Fixes rust-lang#3702
epage added a commit to epage/cargo that referenced this issue Dec 9, 2024
This may look redundant with `CARGO_FEATURE_<CASE_CONVERTED_NAME>=1`
except that doesn't provide a lossless way of getting the names, e.g. for
forwarding for child builds like tests that need to build examples.

This also makes things more consistent as users
conditionalize on features through `cfg` and this even fits with what
the `CARGO_CFG_` docs say:

> For each configuration option of the package being built, this
> environment variable will contain the value of the configuration, where
> <cfg> is the name of the configuration uppercased and having -
> translated to _. Boolean configurations are present if they are set, and
> not present otherwise. Configurations with multiple values are joined to
> a single variable with the values delimited by ,. This includes values
> built-in to the compiler (which can be seen with rustc --print=cfg) and
> values set by build scripts and extra flags passed to rustc (such as
> those defined in RUSTFLAGS). Some examples of what these variables are: 

Fixes rust-lang#3702
epage added a commit to epage/cargo that referenced this issue Dec 9, 2024
This may look redundant with `CARGO_FEATURE_<CASE_CONVERTED_NAME>=1`
except that doesn't provide a lossless way of getting the names, e.g. for
forwarding for child builds like tests that need to build examples.

This also makes things more consistent as users
conditionalize on features through `cfg` and this even fits with what
the `CARGO_CFG_` docs say:

> For each configuration option of the package being built, this
> environment variable will contain the value of the configuration, where
> <cfg> is the name of the configuration uppercased and having -
> translated to _. Boolean configurations are present if they are set, and
> not present otherwise. Configurations with multiple values are joined to
> a single variable with the values delimited by ,. This includes values
> built-in to the compiler (which can be seen with rustc --print=cfg) and
> values set by build scripts and extra flags passed to rustc (such as
> those defined in RUSTFLAGS). Some examples of what these variables are:

Fixes rust-lang#3702
epage added a commit to epage/cargo that referenced this issue Dec 10, 2024
This may look redundant with `CARGO_FEATURE_<CASE_CONVERTED_NAME>=1`
except that doesn't provide a lossless way of getting the names, e.g. for
forwarding for child builds like tests that need to build examples.

This also makes things more consistent as users
conditionalize on features through `cfg` and this even fits with what
the `CARGO_CFG_` docs say:

> For each configuration option of the package being built, this
> environment variable will contain the value of the configuration, where
> <cfg> is the name of the configuration uppercased and having -
> translated to _. Boolean configurations are present if they are set, and
> not present otherwise. Configurations with multiple values are joined to
> a single variable with the values delimited by ,. This includes values
> built-in to the compiler (which can be seen with rustc --print=cfg) and
> values set by build scripts and extra flags passed to rustc (such as
> those defined in RUSTFLAGS). Some examples of what these variables are:

Fixes rust-lang#3702
epage added a commit to epage/cargo that referenced this issue Dec 10, 2024
This may look redundant with `CARGO_FEATURE_<CASE_CONVERTED_NAME>=1`
except that doesn't provide a lossless way of getting the names, e.g. for
forwarding for child builds like tests that need to build examples.

This also makes things more consistent as users
conditionalize on features through `cfg` and this even fits with what
the `CARGO_CFG_` docs say:

> For each configuration option of the package being built, this
> environment variable will contain the value of the configuration, where
> <cfg> is the name of the configuration uppercased and having -
> translated to _. Boolean configurations are present if they are set, and
> not present otherwise. Configurations with multiple values are joined to
> a single variable with the values delimited by ,. This includes values
> built-in to the compiler (which can be seen with rustc --print=cfg) and
> values set by build scripts and extra flags passed to rustc (such as
> those defined in RUSTFLAGS). Some examples of what these variables are:

Fixes rust-lang#3702
github-merge-queue bot pushed a commit that referenced this issue Dec 10, 2024
### What does this PR try to resolve?

This may look redundant with `CARGO_FEATURE_<CASE_CONVERTED_NAME>=1`
except that doesn't provide a lossless way of getting the names, e.g.
for
forwarding to child builds like tests that need to build examples. which
clap does to [test
examples](https://github.com/clap-rs/clap/blob/master/tests/examples.rs).
Maintaining that manually is easy to mess up.

This also makes things more consistent as users
conditionalize on features through `cfg` and this even fits with what
the `CARGO_CFG_` docs say:

> For each configuration option of the package being built, this
> environment variable will contain the value of the configuration,
where
> <cfg> is the name of the configuration uppercased and having -
> translated to _. Boolean configurations are present if they are set,
and
> not present otherwise. Configurations with multiple values are joined
to
> a single variable with the values delimited by , (comma). This
includes values
> built-in to the compiler (which can be seen with rustc --print=cfg)
and
> values set by build scripts and extra flags passed to rustc (such as
> those defined in RUSTFLAGS). Some examples of what these variables
are:

Fixes #3702

### How should we test and review this PR?

### Additional information
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-build-scripts Area: build.rs scripts A-features Area: features — conditional compilation C-feature-request Category: proposal for a feature. Before PR, ping rust-lang/cargo if this is not `Feature accepted` S-needs-design Status: Needs someone to work further on the design for the feature or fix. NOT YET accepted.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants