# Cfg item for detecting no\_std builds

**URL:** <https://internals.rust-lang.org/t/cfg-item-for-detecting-no-std-builds/14783>\
**Category:** language design\
**Created:** [May 27, 2021, 4:02am UTC](https://internals.rust-lang.org/t/cfg-item-for-detecting-no-std-builds/14783 "2021-05-27T04:02:53Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![Michael-F-Bryan](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/michael-f-bryan/32/2815_2.png) [@Michael-F-Bryan](https://internals.rust-lang.org/u/Michael-F-Bryan)\
**Post date:** [May 27, 2021, 4:02am UTC](https://internals.rust-lang.org/t/cfg-item-for-detecting-no-std-builds/14783/1 "2021-05-27T04:02:53Z")

</div>

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.

> <https://github.com/rust-lang/rust/issues/42190>
>
> I'm working on a \`no\_std\` crate that I'd like to test and also compile in a \`std…\` environment. Working with includes is a little painful right now because \`#\[cfg(no\_std)\]\` doesn't seem to work.
> 
> As an example, I'd expect the following code to work both with and without no\_std (commenting out the first line. Instead, it doesn't work as written below (but will work if you comment out \`no\_std\`.
> 
> \`\`\`rust
> \#!\[no\_std\]
> 
> \#\[cfg(no\_std)\]
> use core::mem;
> \#\[cfg(not(no\_std))\]
> use std::mem;
> 
> fn main() {
> let x: u32 = unsafe { mem::uninitialized() };
> }
> \`\`\`
> 
> You'll see the following error:
> \`\`\`shell
> error\[E0432\]: unresolved import \`std::mem\`
> --\> \<anon\>:6:5
> |
> 6 | use std::mem;
> | ^^^^^^^^ Maybe a missing \`extern crate std;\`?
> \`\`\`
> 
> In my crate I'd like to do things like keep \`println!()\` in my crate for testing during development, but have them work during testing. And also configure the entire module to be \`no\_std\` when not testing using \`#!\[cfg\_attr(not(test), no\_std)\]\`. Neither of these work because of the current situation.
> 
> cc @japaric This is something I mentions in your users forum thread about embedded dev.

---

<div class="post-metadata">

**Author:** ![jhpratt](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/jhpratt/32/11640_2.png) [@jhpratt](https://internals.rust-lang.org/u/jhpratt)\
**Post date:** [May 27, 2021, 4:13am UTC](https://internals.rust-lang.org/t/cfg-item-for-detecting-no-std-builds/14783/2 "2021-05-27T04:13:28Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![Michael-F-Bryan](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/michael-f-bryan/32/2815_2.png) [@Michael-F-Bryan](https://internals.rust-lang.org/u/Michael-F-Bryan)\
**Post date:** [May 27, 2021, 4:29am UTC](https://internals.rust-lang.org/t/cfg-item-for-detecting-no-std-builds/14783/3 "2021-05-27T04:29:36Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![CAD97](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/cad97/32/3460_2.png) [@CAD97](https://internals.rust-lang.org/u/CAD97)\
**Post date:** [May 27, 2021, 5:36pm UTC](https://internals.rust-lang.org/t/cfg-item-for-detecting-no-std-builds/14783/4 "2021-05-27T17:36:17Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![system](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/system/32/14092_2.png) [@system](https://internals.rust-lang.org/u/system)\
**Post date:** [August 25, 2021, 5:37pm UTC](https://internals.rust-lang.org/t/cfg-item-for-detecting-no-std-builds/14783/5 "2021-08-25T17:37:04Z")

</div>

Closed on August 25, 2021, 5:37pm UTC

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.
