Creating a library with both `std` and `no_std` methods


I’m wanting to write a library that will work both on embedded devices with out any filesystem, but then also work on devices with an operating system.

For example:

// With "no_std": An embedded device, where `vec_data` is some valid vector data.
let x3 = new X3();
let x3_encoded = x3.encode(vec_data);

// With "std": above code should work fine, but also the following:
let x3_encoded_from_file = X3.fromFile("/path/to/my/file.dat");

How would I structure the crate such that the module will include "std" components when the target is an operating system, and "no_std" when the target is an embedded device?


You can use feature flags, set it up so if the feature is selected you enable the std part of the library. Then the users of your crate can decide which they want.


“Feature flags”, that’s the key. I’ve seen them, but haven’t used or understood them yet. Thanks for the quick response. Time to do some reading.


Feature flags are flags that the user of your crate can pass to the compiler to allow conditional compilation of a crate. I would look in the Cargo Book and look up stuff about the cfg macro and attribute as they go hand in hand with feature flags.


Can one have different feature sets enabled (i.e. std/no_std) for test or examples and cross-compiling?

I’m working on a no_std crate where I use libm for the f32/f64 traits but for unit-testing and examples I was planning on using the primitive f32 methods


You can annotate your test like this

#[cfg(feature = "std")]
fn test() {
// do my thing with primitive f32 methods

#[cfg(feature = "std")] tells the compiler to only compile this if std is there else it just ignore it.