rust-lang / rust

Empowering everyone to build reliable and efficient software.
https://www.rust-lang.org
Other
99.03k stars 12.79k forks source link

#![cfg] to disable a crate disables #![no_std] #39183

Open retep998 opened 7 years ago

retep998 commented 7 years ago

Using #![cfg] to disable a crate on platforms where it makes no sense is usually a great idea. That way people can unconditionally depend on your crate and use it only on the targets where it is needed. However it disables the entire crate, including all global attributes, which means normally a crate that has #![no_std] wouldn't depend on std, but if you use #![cfg] to disable that crate, suddenly it does depend on std! The only workaround is to not use #![cfg] and instead manually disable each item in the lib.rs, except for specific attributes like #![no_std].

For example:

// rustc foo.rs --crate-type=rlib
#![no_std]
#![cfg(any())]
// rustc bar.rs -Zprint-link-args -Lcrate=current_directory
#![no_std]
extern crate foo;
fn main() {}

Observe as libstd is passed to the linker despite both crates using #![no_std].

KalitaAlexey commented 7 years ago

@retep998, Please include some example.

Mark-Simulacrum commented 7 years ago

@retep998 What would you suggest we should do in this case? I thought about just including #![no_std] if it's being disabled through #![cfg] but I'm not sure we can/should do that: it seems like non-obvious behavior, and may be difficult to implement. I agree that this is a painful problem though.

retep998 commented 7 years ago

I think what would work is to detect when the crate root is disabled via #![cfg] and if so, make the crate automatically #![no_core], with no implicit preludes or extern crates.

Mark-Simulacrum commented 7 years ago

So maybe as a more general formula empty crates (those that define no items?) should be #![no_core] or the equivalent thereof?

retep998 commented 7 years ago

It's not like an empty crate has anything that could possibly care about having core or std anyway, so being more general like that is probably fine.