Cfg item for detecting no_std builds

At the moment, when writing a Rust crate which optionally supports the standard library you need to add cargo feature (typically called std) and wrap the code requiring the standard library in #[cfg(feature = "std")].

Furthermore, if you have dependencies which themselves may also require the standard library, you need to manually determine which feature flag they use and edit your Cargo.toml to enable to that feature whenever your std is enabled.

Would people be open to adding a new std configuration option (i.e. #[cfg(std)]) which is automatically enabled whenever any crate within the dependency tree is compiled without #![no_std]?

The use cases I have in mind are:

  • being able to automatically include std::error::Error impls or implement a trait on items from the standard library
  • making sure a crate is never used with the standard library (e.g. #[cfg(std)] compile_error!("This crate will not work outside an embedded context")) so you get a user-friendly compile error instead of the more confusing "the std component for this target isn't installed"
  • Providing a single blessed convention for creating no_std crates which doesn't require manually propagating feature flags all the time
  • Lower the barrier to entry for writing crates which work without the standard library by default

There is already a similar issue by @susurrus from a couple years ago, but I'm wondering if opinions have changed since then.

1 Like

#[cfg(accessible(::std))] should work in the future, no? Or would this not work because you're thinking of cross-crate functionality?

A #[cfg(accessible(::std))] sounds like it's checking if a particular item is accessible from the current context so that would only work if your own crate is conditionally adding #![no_std], wouldn't it?

A large part of what I'm thinking about involves some sort of implicit cross-crate mechanism for detecting whether the final binary will be linked to the standard library. Preferably without every crate along the way needing to create a std feature and propagate it up the dependency tree.

A std feature goes a long way to communicating that a crate supports conditional no_std. This could be just replaced with the advertising of implicit no_std compatibility, but fundamentally, adding features that depend on std is fundamentally equivalent to a feature.

That said, being able to conditionally add support for a crate based on if it is in tree rather than just if a feature is enabled is something that has been asked for before.

But for the specific case of std, this causes a significant problem: it's impossible to test no_std code paths (that don't use std-requiring optimizations) with the standard test harness, which requires std.

1 Like