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

Conditional compilation of dependency feature based on target doesn't work #2524

Closed
PaulGrandperrin opened this issue Mar 27, 2016 · 20 comments
Assignees
Labels
A-features Area: features — conditional compilation C-bug Category: bug E-hard Experience: Hard

Comments

@PaulGrandperrin
Copy link

Here is my use case:
The crate hyper can be compiled with or without SSL.
The target_env gnu compiles fine with SSL whereas musl (for static linking) doesn't.

Here is what I'd like to do:

# By default compile hyper with SSL except when target_env is musl
[target.'cfg(not(target_env = "musl"))'.dependencies]
hyper = {version="*", features=["ssl"], default-features = false}

# When target_env is musl, compile hyper without SSL
[target.'cfg(target_env = "musl")'.dependencies]
hyper = {version="*", default-features = false}

It doesn't work as intented, the hyper/ssl feature compilation is tried whatever the target platform.
I'm using cargo 0.10.0-nightly (4e6434d 2016-03-24).

@alexcrichton
Copy link
Member

Hm this is indeed surprising!

I think that this can work, but it doesn't lend itself well to the current implementation. We currently record "activated features" in resolve, but we probably need to delay what was actually activated until the very end when we're compiling crates as that's where the filtering of target-specific dependencies and such actually happens.

@alexcrichton alexcrichton added C-bug Category: bug E-hard Experience: Hard labels Mar 28, 2016
mbrubeck added a commit to mbrubeck/servo that referenced this issue May 5, 2016
Servo currently enabled the `release_max_level_info` feature for the log crate
in an Android-specific dependency.  Currently this works for all platforms
because of rust-lang/cargo#2524, but it might break if that issue is fixed.
bors-servo pushed a commit to servo/servo that referenced this issue May 6, 2016
Set max log level on all platforms

Servo currently enabled the `release_max_level_info` feature for the log crate
in an Android-specific dependency.  Currently this works for all platforms
because of rust-lang/cargo#2524, but it might break if that issue is fixed.

<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="35" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/11033)
<!-- Reviewable:end -->
zakorgy pushed a commit to zakorgy/servo that referenced this issue May 26, 2016
Servo currently enabled the `release_max_level_info` feature for the log crate
in an Android-specific dependency.  Currently this works for all platforms
because of rust-lang/cargo#2524, but it might break if that issue is fixed.
@dthul
Copy link

dthul commented Jun 1, 2017

Are there any news on this issue?
I have the exact same problem with the "blas" crate. I want to disable its default features on Windows (since they break the build) but use the default features on Linux. My current setup:

[target.'cfg(not(windows))'.dependencies.blas]
version = "0.15.4" # We use the standard options on Linux (meaning building OpenBLAS during compilation)

[target.'cfg(windows)'.dependencies.blas]
version = "0.15.4"
default-features = false # We take care of linking a BLAS implementation on Windows ourselves (see build.rs)

Is there a workaround or do I have to modify Cargo.toml manually according to my target?

@fuine
Copy link

fuine commented Jun 15, 2017

I believe I have the same problem, while trying to use specific feature in x11 crate only if a specific feature in my crate is set:

[target.'cfg(feature="my_xss")'.dependencies]
x11 = {version = "2.14", features = ["xlib", "xss"]}
[target.'cfg(not(feature="my_xss"))'.dependencies]
x11 = {version = "2.14", features = ["xlib"]}

[features]
my_xss = []

No matter what features the crate is compiled with, it always compiles x11 with xss feature. Is this supposed to be happening?

@axos88
Copy link

axos88 commented Mar 17, 2018

I'm also unable to cross-compile my project to both raspberry and x86_64 for testing due to this not working:

[target.'cfg(not(target_arch = "arm"))'.dependencies]
wiringpi = { version = '0.2.4' }

[target.'cfg(target_arch = "arm")'.dependencies]
wiringpi = { version = '0.2.4', features = ["development"] }

The latter would stub the wiringpi libary and just log the usage, which should be good for testing it on my development machine... Currently it doesn't compile because it's looking for a .so file that does not exist for anything other than an arm

@yrashk
Copy link

yrashk commented Apr 30, 2018

I have the same problem depending on a path-addressed crate with features determined by target_arch.

@Hywan
Copy link

Hywan commented Jun 21, 2018

Same problem here with nom with default features or not depending of the target.

Hywan added a commit to Hywan/gutenberg-parser-rs that referenced this issue Jun 22, 2018
…tly.

`rustc` nightly is required for `no_std`, which is required only for
the WASM target. nom needs to be used with the feature `alloc` in this
particular case. So to get stable for every other targets, we should
write:

```toml
[target.'cfg(feature = "wasm")'.dependencies]
nom = { version = "4.0.0", default-features = false, features = ["alloc"] }

[target.'cfg(not(feature = "wasm"))'.dependencies]
nom = { version = "4.0.0" }
```

Sadly, it does not work, see rust-lang/cargo#2524.

The only alternative I found so far, is to use 2 `Cargo.toml`
files. Next commits are likely to split the repository into Cargo
workspaces.
hcpl added a commit to hcpl/serde_mtproto that referenced this issue Nov 11, 2018
That's because there are following requirements:
* Tests should work for pre-1.26 and post-1.26 Rust alike;
* Benchmarks depend on 128-bit integer support from Rand.

The issue is that Rand 0.5 supports that via Cargo feature flag, not
`rustc` version detection and `cfg`-dependent feature selection doesn't
work: <rust-lang/cargo#2524>.

A solution is to have a crate just for benchmarking. The directory
structure looks like this because there are plans to use Criterion for
benchmarking on stable and beta Rusts.
hcpl pushed a commit to hcpl/serde_mtproto that referenced this issue Nov 11, 2018
Move benchmarks to an inner crate

That's because there are following requirements:
* Tests should work for pre-1.26 and post-1.26 Rust alike;
* Benchmarks depend on 128-bit integer support from Rand.

The issue is that Rand 0.5 supports that via Cargo feature flag, not
`rustc` version detection and `cfg`-dependent feature selection doesn't
work: <rust-lang/cargo#2524>.

A solution is to have a crate just for benchmarking. The directory
structure looks like this because there are plans to use Criterion for
benchmarking on stable and beta Rusts.
@MarcioPorto
Copy link

Any news on this issue? I am encountering the exact same problem as @axos88 and @fuine. If not, is there maybe a workaround to solve the issue temporarily?

@elichai

This comment has been minimized.

@waynenilsen

This comment has been minimized.

@ehuss ehuss added the A-features Area: features — conditional compilation label Apr 12, 2019
@vhnatyk

This comment has been minimized.

@zakarumych
Copy link

How cfg dependencies filtering happens? Maybe we could make it happen immediatelly when cargo parses next Cargo.toml?

gecko-dev-updater pushed a commit to marco-c/gecko-dev-comments-removed that referenced this issue Oct 1, 2019
…ck:max-log); r=metajack

Servo currently enabled the `release_max_level_info` feature for the log crate
in an Android-specific dependency.  Currently this works for all platforms
because of rust-lang/cargo#2524, but it might break if that issue is fixed.

Source-Repo: https://github.com/servo/servo
Source-Revision: ab12d8098fcc0517b64643d25683e2e15e665410

UltraBlame original commit: e1ac9162c087971de3a15094972cd44a45378bf5
gecko-dev-updater pushed a commit to marco-c/gecko-dev-wordified-and-comments-removed that referenced this issue Oct 1, 2019
…ck:max-log); r=metajack

Servo currently enabled the `release_max_level_info` feature for the log crate
in an Android-specific dependency.  Currently this works for all platforms
because of rust-lang/cargo#2524, but it might break if that issue is fixed.

Source-Repo: https://github.com/servo/servo
Source-Revision: ab12d8098fcc0517b64643d25683e2e15e665410

UltraBlame original commit: e1ac9162c087971de3a15094972cd44a45378bf5
gecko-dev-updater pushed a commit to marco-c/gecko-dev-wordified that referenced this issue Oct 1, 2019
…ck:max-log); r=metajack

Servo currently enabled the `release_max_level_info` feature for the log crate
in an Android-specific dependency.  Currently this works for all platforms
because of rust-lang/cargo#2524, but it might break if that issue is fixed.

Source-Repo: https://github.com/servo/servo
Source-Revision: ab12d8098fcc0517b64643d25683e2e15e665410

UltraBlame original commit: e1ac9162c087971de3a15094972cd44a45378bf5
@johanlindfors
Copy link

I seem to have the exact same issue when trying to get SDL2 to build properly on MacOS and Windows.

[target.'cfg(target_os = "macos")'.dependencies]
sdl2 =  { version = "0.32.2", features = ["bundled"]}

[target.'cfg(target_os = "windows")'.dependencies]
sdl2 =  { version = "0.32.2", features = ["bundled", "static-link"]}

But my Mac OS device still fails to build SDL2, since it's trying to use the static-link feature. Any suggestion on how to solve this?

@MaksymZavershynskyi
Copy link

Same issue.

[target.'cfg(target_arch = "wasm32")'.dependencies]
near-vm-logic = {version = "0.3.1", features = [], default-features = false }

[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
near-vm-logic = {version = "0.3.1", features = ["mocks"], default-features = false }
lazy_static = "1.4.0"

@niklasad1
Copy link

@johanlindfors a workaround could be:

[dependencies]
sdl2 =  { version = "0.32.2", default-features = false }

[features]
default = []
sdl2_windows = ["sdl2/bundled", "sdl2/static-link"]
sdl2_mac = ["sdl2/bundled"]

But it would require you to explicitly specify the features when building

@johanlindfors
Copy link

Thanks, that workaround will help. I guess this is still considered a bug, because the documented behavior clearly doesn't seem to work.

@stevemk14ebr
Copy link

stevemk14ebr commented Oct 29, 2019

[target.'cfg(windows)'.build-dependencies]
winreg = "0.6"

Fails to detect debian in a docker container, using image: FROM rust:1.36.0 AS builder and executing RUN cargo build-deps --release. This causes winreg to be built which obviously fails. Can we please get a fix!?

This is the suggested rustc docker image using the suggested conditional compilation feature. IMHO this should either be fixed immediately or the official documentation ammended/removed.

EDIT: apparently build-deps does not respect the cfg tag at all. Switching to cargo build works. !?!?

@ehuss
Copy link
Contributor

ehuss commented Feb 24, 2020

Target-specific features for dependencies has been implemented and is available as a nightly-only feature on the latest nightly 2020-02-23. See the tracking issue at #7914.

If people following this issue could try it out, and leave your feedback on the tracking issue (#7914), I would appreciate it. Particularly we'd like to know if it helps your project and does it cause any breakage?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-features Area: features — conditional compilation C-bug Category: bug E-hard Experience: Hard
Projects
None yet
Development

No branches or pull requests