#![cfg] to disable a crate disables #![no_std]
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].
@retep998, Please include some example.
Alexey at 2017-01-19 18:46:33
@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.Mark Rousskov at 2017-05-20 01:53:40
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.Peter Atashian at 2017-05-20 03:29:15
So maybe as a more general formula empty crates (those that define no items?) should be
#![no_core]or the equivalent thereof?Mark Rousskov at 2017-05-20 03:31:08
It's not like an empty crate has anything that could possibly care about having
coreorstdanyway, so being more general like that is probably fine.Peter Atashian at 2017-05-20 03:43:58