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

Enabling target features in .cargo/config does not work for cfg statements in Cargo.toml #6858

Closed
newpavlov opened this issue Apr 17, 2019 · 8 comments · Fixed by #11114
Closed
Labels
A-configuration Area: cargo config files and env vars C-bug Category: bug

Comments

@newpavlov
Copy link

newpavlov commented Apr 17, 2019

Originally reported in RustCrypto/stream-ciphers#11

Create a project with following files. Cargo.toml:

[target.'cfg(target_feature="aes")'.dependencies]
either = "*"

.cargo/config:

[target.'cfg(any(windows, unix))']
rustflags = ["-Ctarget-feature=+aes"]

src/main.rs:

#[cfg(target_feature="aes")]
fn main() { println!("aes enabled"); }

#[cfg(not(target_feature="aes"))]
fn main() { println!("aes disabled"); }

Running cargo run outputs "aes disabled" as expected, but either crate does not get downloaded, i.e. cfg statement in Cargo.toml does not work as expected. And as a consequence adding #[cfg(target_feature="aes")] extern crate either; to main.rs results in a compilation error. Meanwhile RUSTFLAGS="-C target-feature=+aes" cargo run works as expected without any issues.

@newpavlov newpavlov added the C-bug Category: bug label Apr 17, 2019
@ehuss
Copy link
Contributor

ehuss commented Apr 29, 2019

This is an interesting problem. There's a circular requirement where to determine the cfg flags it needs to know the cfg flags. Cargo currently starts with an empty set (see TargetInfo) and runs rustc to determine the starting cfg set. To handle this situation, it would need to repeatedly call rustc to build up the cfg rules until it stabilizes. My instinct is that is not practical, or at least would be complex or slow. However, I can't think of any other way around it (other than, as you mention, using the RUSTFLAGS env var, and enabling that using some external script or tool).

@ehuss ehuss added the A-configuration Area: cargo config files and env vars label Apr 29, 2019
zonyitoo added a commit to shadowsocks/shadowsocks-rust that referenced this issue Aug 20, 2020
@posix4e
Copy link

posix4e commented Dec 7, 2020

Any updates?

@d-e-s-o
Copy link
Contributor

d-e-s-o commented Jan 18, 2021

The same issue seems to affect cfg(debug_assertions). Debugging this kind of stuff can be a huge time sink. At the very least we should be printing a warning, in my opinion.

@daladim
Copy link

daladim commented Oct 29, 2021

I've just run into this problem when trying to conditionally build tokio-console (that itself declares a condtional dependency based on rustflags).

I have crafted another minimal reproducer that you can try at https://github.com/daladim/cargo-target-cfg-evaluation-order-bug

daladim pushed a commit to JustRustThings/tokio that referenced this issue Oct 29, 2021
daladim pushed a commit to JustRustThings/tokio that referenced this issue Nov 8, 2021
daladim pushed a commit to JustRustThings/tokio that referenced this issue Nov 16, 2021
daladim pushed a commit to JustRustThings/tokio that referenced this issue Nov 17, 2021
daladim pushed a commit to JustRustThings/tokio that referenced this issue Jan 18, 2022
poliorcetics pushed a commit to JustRustThings/tokio that referenced this issue Feb 10, 2022
poliorcetics pushed a commit to JustRustThings/tokio that referenced this issue May 4, 2022
@Systemcluster
Copy link
Contributor

Systemcluster commented Jun 5, 2022

This should be strongly noted in the documentation.

It notes Do not try to match on debug_assertions or Cargo features like feature="foo", but from @ehuss's comment "Cargo currently starts with an empty set" I understand that cfg directives in .cargo/config don't work at all.

I spent around a day trying to set -Ctarget-feature and -Ctarget-cpu based on cfg targets in .cargo/config, and it took me quite a bit to find this issue.

Running cargo run outputs "aes disabled" as expected

I don't think this is expected at all. With a config like

[target.'cfg(any(windows, unix))']
rustflags = ["-Ctarget-feature=+aes"]

I would expect the aes feature to be enabled for all windows and unix targets, and as currently documented this is very non-intuitive. In fact, the documentation even lists it as an example, which is very misleading in light of this issue and #10439:

[target.'cfg(all(target_arch = "arm", target_os = "none"))']
runner = "my-arm-wrapper"
rustflags = ["", ""]

@ehuss
Copy link
Contributor

ehuss commented Jun 5, 2022

Adding this limitation to the documentation sounds good to me.

I understand that cfg directives in .cargo/config don't work at all.

cfg directives should work. This issue is just about having a dependency between .cargo/config.toml and dependencies in Cargo.toml. An expression like cfg(any(windows, unix)) will set the given rustflags on those platforms, and will be able to see that from #[cfg] attributes. It's just that you can't key off it in a target dependencies table.

If you are not able to get cfg expressions to work (and that aren't involved with Cargo.toml), feel free to open a new issue with a reproduction.

@Systemcluster
Copy link
Contributor

If you are not able to get cfg expressions to work (and that aren't involved with Cargo.toml), feel free to open a new issue with a reproduction.

I might be misreading the issue, but I think #10439 was describing the behavior without involvement of Cargo.toml, and got closed in favor of this one.

Thanks to your answer I tested it a bit further and it appears that rustflags in a cfg target (additionally to not affecting Cargo.toml) only don't affect the CARGO_CFG_TARGET_FEATURE environment variable available to build.rs, while still affecting the actual compilation. This threw me off the track a bit, as I was using that variable in a build.rs to try to figure out the rustflags interactions.

Is there another way to query which target-features are enabled for a build, without querying each one with conditional compilation individually?

@ehuss
Copy link
Contributor

ehuss commented Jun 5, 2022

Yea, cfg settings affected by target.'…'.rustflags in a config won't show up in build scripts, either.

Unfortunately, I can't think of a workaround to detect those settings from a build script. You could perhaps run rustc --print=cfg along with CARGO_ENCODED_RUSTFLAGS as arguments, and parse the output?

poliorcetics pushed a commit to JustRustThings/tokio that referenced this issue Jun 8, 2022
poliorcetics pushed a commit to JustRustThings/tokio that referenced this issue Jul 19, 2022
vthib pushed a commit to JustRustThings/tokio that referenced this issue Sep 9, 2022
@bors bors closed this as completed in f6de921 Sep 27, 2022
poliorcetics pushed a commit to JustRustThings/tokio that referenced this issue Jan 26, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-configuration Area: cargo config files and env vars C-bug Category: bug
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants