You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This is a tracking issue for progress on a no_std compatible subset of Bevy. The tasks are ordered roughly in sequence (bevy_app can't be no_std until bevy_ecs is for example).
Overview
Below is a visualisation of the crates planned to be ported to no_std. Edges indicate the primary blocker for a crate being ported. The 🚧 symbol indicates that this crate is in-progress, while ✅ indicates it is now available in no_std.
Provide an appropriate Instant type which can be controlled by the user in no_std contexts, or avoid its use. Move web-time into wasm32-only dependencies (doesn't need to exist outside web anyway!). Make thread_local optional.
Update derive_label to use Box from alloc (requires wrapping the quoted impl in a const _: () = { ... } so that extern crate alloc wont conflict with the outer namespace).
Once the other core tasks are completed, a no_std example should be created and tested in CI as well.
Bonus Features
These tasks aren't strictly required, but should be completed to close the gap between no_std and std Bevy. The more functionality we can provide in no_std, the more the community can develop for it.
This crate iswas blocked on AccessKit's lack of no_std support. @DataTriny pointed out AccessKit 0.17 now supports no_std! This should now be quite straightforward to add no_std support to once the other internal blockers are resolved (bevy_app, etc.)
Reliance on filesystem operations will make this interesting, but a lot of the asset functionality exists outside of files and folders (processing, etc.). It's reasonable to consider that a no_std platform could have a custom AssetSource (and accompanying AssetReader/Writer/etc.).
Blocked on bevy_hierarchy and a design. Currently built around networking, but could support serial commands instead, and would make debugging on embedded much easier too.
These crates can't be ported to no_std because they are highly platform specific. If you see something on this list that could be ported, please let me know!
Replace petgraph with a no_std compatible alternative.
Currently only using the DiGraph type with no edge data and only a single node type AnimationGraphNode (and a serializable alternate SerializedAnimationGraphNode).
bevy_audio ⚠
Currently undergoing a major re-write so this is subject to change. I suspect even with the re-write no_std support would be blocked on a fundamental dependency such as cpal. Like rendering, audio is very platform dependent so there likely isn't a viable API Bevy could provide that would be simultaneously feature-rich enough for use on common platforms (PC, etc.) while being low-level enough for no_std ones too.
Unfamiliar with the dynamic linking this crate provides. I don't see any reason why it couldn't be supported in no_std, but I would definitely require an SME to assist with getting it working.
bevy_encase_derive ⚠
Exclusively used with encase, which is a part of the rendering side of Bevy.
Built around gilrs which does not currently have any no_std support. There might be a way to upstream no_std support by relying on something like SDL, but I'm not familiar enough with the project to make a fair assessment on the viability here.
Blocked by bevy_render. It may make sense to find a way to break this dependency, since gLTF can be used independently of wgpu (e.g., with a user-created OpenGL renderer backend), but this would need an SME for sure.
Massive crate very deeply integrated with wgpu, which is not just std reliant, but also platform dependent too. I don't think it will ever make sense to have a no_stdbevy_render. Maybe could have value in splitting out some abstractions, but I don't know.
Blocked on winit. Likely couldn't be made no_std upstream either since it's entirely platform dependent.
General Notes
thiserror
Note: this is now outdated, as thiserror version 2 includes no_std support and is now publicly available.
thiserror is currently not available in a no_std form due to its use of the ::std::error::Error path for Error (which it continues to use for MSRV backwards compatibility). There is a PR to add no_std support to thiserror which preserves that MSRV requirement, but it's unclear if/when that will be merged and released.
One alternative is to link against the PR instead of the published version of thiserror:
Another alternative is to switch to using derive_more. This would require adding explicit calls to derive(From, Display) as well, which adds to the noise. Additionally, it isn't already in the dependency tree, so its inclusion may be contentious.
Due to delays in thiserror's no_std support, we have decided to use derive_more.
portable-atomic
Certain platforms, such as the Raspberry Pi Pico, could run Bevy once no_std support is added, but can't due to Bevy's use of certain atomic features. To work around this issue, Bevy should employ portable-atomic and its sibling portable-atomic-util. These crates provide suitable replacements for the various AtomicX types and Arc.
This adds cfg(...) burden to the project, but would be limited in scope to bevy_ecs and bevy_tasks (the largest users of atomic types), at least initially. Additionally, there is issue with coercion since portable_atomic_util::Arc is a 3rd party smart-pointer, so you cannot, for example, create an Arc<dyn T> directly from an Arc<impl T>. There is a simple workaround, but at a small performance cost for unsized types. However, this will be resolved once #18598 stabilises.
Platform Support
Being no_std is necessary for certain platforms, but it is not always sufficient. Below is a table of platforms that I have tested:
Name
Target
Builds
Notes
UEFI
x86_64-unknown-uefi
Runs
Boots on emulated and real hardware, supported by the uefi crate.
GameBoy Advance
thumbv4t-none-eabi
Partially
The platform does not support all atomic operations (e.g., CAS), which Bevy directly and transiently relies on. Moving from tracing to log, and using portable_atomics is sufficient to make this platform compile.
Nintendo Switch
aarch64-nintendo-switch-freestanding
Compiles
I cannot test the binary produced by cargo nx on real hardware or an emulator to confirm it actually works.
PlayStation One
mipsel-sony-psx
Partially
The platform does not support all atomic operations (e.g., CAS), which Bevy directly and transiently relies on. Moving from tracing to log, and using portable_atomics is sufficient to make this platform compile.
MSP430
msp430-none-elf
No
This platform is 16-bit, which breaks too many assumptions made by dependencies like zerocopy.
Playdate
thumbv7em-none-eabihf
Runs
Runs but requires a patch to fixedbitset to disabled SIMD. Could potentially be fixed from within Bevy without the patch though.
Raspberry Pi Pico
thumbv6m-none-eabi
Runs
Runs but requires adopting portable_atomics within Bevy, since the Pico doesn't support the atomic CAS instructions required.
I have a prototype of no_std compatible Bevy available on this branch. It's not being actively maintained, as it is a proof of concept for upstream no_std support (use at your own risk, etc.). However, if anyone has a particular platform they'd like to use Bevy on, please feel free to test using this branch and let me know what kind of compatibility you have. In general:
You must be able to compile a Rust project for this platform. (I hope this goes without saying!)
You must have alloc and core available.
Your platform must support Atomic CAS (hoping to relax this in the future!)
Only the bevy_app, bevy_ecs, bevy_utils, and bevy_tasks are compatible in this branch, and must be imported directly (e.g., you can't use bevy;, instead use bevy_app;). Additionally, you must disable default features for no_std compatibility.
I've posted a more detailed write-up here. But as a succinct warning: no_std crates should unconditionally be #[no_std] to ensure consistent implicit prelude.
As of Rust 1.84, wasm32v1-none has been stabilised as a tier 2 (no_std) target. This is notable compared to the existing wasm32-unknown-unknown target in that it doesn't enable new proposals as they're stabilised. This massively improves browser compatibility at the expense of some performance and functionality.
As stated, this new target is strictly no_std. This avoids the stubbed-out version of std that wasm32-unknown-unknown has, which panics when attempting to use unsupported APIs. This has the interesting side-effect of motivating previously disinterested parties into supporting no_std. A highly relevant example of this is wgpu. With wgpu potentially gaining no_std support, the possibility of bevy_render and all of its downstream crates becoming no_std compatible themselves goes from an outright impossibility to a potentially desirable mainstream feature.
Footnotes
bevy_core has been removed, effectively resolving its no_std compatibility. ↩
This is a tracking issue for progress on a
no_stdcompatible subset ofBevy. The tasks are ordered roughly in sequence (bevy_appcan't beno_stduntilbevy_ecsis for example).Overview
Below is a visualisation of the crates planned to be ported to
no_std. Edges indicate the primary blocker for a crate being ported. The 🚧 symbol indicates that this crate is in-progress, while ✅ indicates it is now available inno_std.graph TD; bevy_a11y[bevy_a11y ✅] bevy_app[bevy_app ✅] bevy_asset bevy_color[bevy_color ✅] bevy_core[bevy_core* ✅] bevy_diagnostic[bevy_diagnostic ✅] bevy_ecs[bevy_ecs ✅] bevy_hierarchy[bevy_hierarchy* ✅] bevy_input[bevy_input ✅] bevy_input_focus[bevy_input_focus ✅] bevy_math[bevy_math ✅] bevy_mikktspace[bevy_mikktspace ✅] bevy_ptr[bevy_ptr ✅] bevy_reflect[bevy_reflect✅] bevy_state[bevy_state ✅] bevy_tasks[bevy_tasks ✅] bevy_time[bevy_time ✅] bevy_transform[bevy_transform ✅] bevy_utils[bevy_utils ✅] bevy_window[bevy_window ✅] bevy_ptr-->bevy_ecs; bevy_utils-->bevy_ecs; bevy_tasks-->bevy_ecs; bevy_ecs-->bevy_app; bevy_app-->bevy_core; bevy_app-->bevy_a11y; bevy_app-->bevy_asset; bevy_app-->bevy_time; bevy_app-->bevy_log; bevy_core-->bevy_input; bevy_core-->bevy_diagnostic; bevy_core-->bevy_hierarchy; bevy_asset-->bevy_image; bevy_asset-->bevy_scene; bevy_color-->bevy_image; bevy_mikktspace-->bevy_mesh; bevy_hierarchy-->bevy_remote; bevy_hierarchy-->bevy_state; bevy_hierarchy-->bevy_transform; bevy_hierarchy-->bevy_input_focus; bevy_transform-->bevy_mesh; bevy_transform-->bevy_scene; bevy_math-->bevy_input; bevy_math-->bevy_color; bevy_input-->bevy_window; bevy_input_focus-->bevy_a11y; bevy_window-->bevy_input_focus; bevy_reflect-->bevy_ecs; bevy_image-->bevy_mesh;Core Tasks
These tasks must be completed for a
no_stdBevy to become usable at all.Prerequisites ✅
coreandallocoverstdLints #15281bevy_ptr✅Done prior to initiative.
bevy_utils✅bevy_utilsinno_std#15463Provide an appropriate
Instanttype which can be controlled by the user inno_stdcontexts, or avoid its use. Moveweb-timeintowasm32-only dependencies (doesn't need to exist outside web anyway!). Makethread_localoptional.Done!
bevy_tasks✅no_stdsupport tobevy_tasks#15464Done!
bevy_macro_utils✅derive_labelto supportno_stdenvironments #15465Update
derive_labelto useBoxfromalloc(requires wrapping the quotedimplin aconst _: () = { ... }so thatextern crate allocwont conflict with the outer namespace).Done!
bevy_ecs✅petgraphfrombevy_ecs#15519thiserrorfrombevy_ecs#15774no_stdsupport tobevy_ecs#16758Done!
bevy_app✅thiserrorfrombevy_app#15779no_stdsupport tobevy_app#16874Merged!
bevy_core1 ✅bevy_core#16897Merged!
bevy_internal/bevystd/allocfeatures from sub-crates through to the finalbevycrate.Blocked on
bevy_core.CI 🚧
compile-check-no-stdCommand to CI Tool #15843no_stdexample should be created and tested in CI as well.Bonus Features
These tasks aren't strictly required, but should be completed to close the gap between
no_stdandstdBevy. The more functionality we can provide inno_std, the more the community can develop for it.bevy_a11y✅no_stdSupport tobevy_a11y#17505Done!
This crate
iswas blocked on AccessKit's lack ofno_stdsupport. @DataTriny pointed out AccessKit 0.17 now supportsno_std! This should now be quite straightforward to addno_stdsupport to once the other internal blockers are resolved (bevy_app, etc.)bevy_assetthiserrorfrombevy_asset#15778Reliance on filesystem operations will make this interesting, but a lot of the asset functionality exists outside of files and folders (processing, etc.). It's reasonable to consider that a
no_stdplatform could have a customAssetSource(and accompanyingAssetReader/Writer/etc.).bevy_color✅no_stdsupport tobevy_color#16633thiserrorfrombevy_color#15777Done!
bevy_deriveShould work as-is, but need to test.
bevy_diagnostic✅no_stdsupport tobevy_diagnostic#17507Done!
bevy_hierarchy2 ✅no_stdsupport tobevy_hierarchy#16998Merged!
bevy_imagethiserrorfrombevy_image#15771Blocked on
bevy_asset. Would also require some substantial feature-gating to isolate out theno_stdcompatible subset.bevy_input✅thiserrorfrombevy_input#15770no_stdsupport tobevy_input#16995Awaiting merge.
bevy_input_focus✅no_stdSupport forbevy_input_focus#17490Done!
bevy_logBlocked on
bevy_ecs.bevy_math✅no_stdSupport tobevy_math#15810thiserrorfrombevy_math#15769Done!
bevy_meshthiserrorfrombevy_mesh#15768Blocked on
bevy_image,bevy_transform, andhexasphere.hexaspherewould need upstream changes, but on a first-glance looks like to could beno_std.bevy_mikktspace✅no_stdsupport tobevy_mikktspace#15528Done!
bevy_reflect✅no_stdsupport tobevy_reflect#16256thiserrorfrombevy_reflect#15766Done!
bevy_remoteBlocked on
bevy_hierarchyand a design. Currently built around networking, but could support serial commands instead, and would make debugging on embedded much easier too.bevy_scenethiserrorfrombevy_scene#15764Blocked on
bevy_hierarchyandbevy_asset.bevy_state✅no_stdsupport tobevy_state#17028Done!
bevy_time✅thiserrorfrombevy_time#15759no_stdSupport tobevy_time#17491Done!
bevy_transform✅thiserrorfrombevy_transform#15761no_stdsupport tobevy_transform#17030Merged!
bevy_window✅no_stdsupport tobevy_window#17031Merged!
Not Planned
These crates can't be ported to
no_stdbecause they are highly platform specific. If you see something on this list that could be ported, please let me know!bevy_animation⚠Blocked by
bevy_render.thiserrorfrombevy_animation#15780petgraphwith ano_stdcompatible alternative.Currently only using the
DiGraphtype with no edge data and only a single node typeAnimationGraphNode(and a serializable alternateSerializedAnimationGraphNode).bevy_audio⚠Currently undergoing a major re-write so this is subject to change. I suspect even with the re-write
no_stdsupport would be blocked on a fundamental dependency such ascpal. Like rendering, audio is very platform dependent so there likely isn't a viable API Bevy could provide that would be simultaneously feature-rich enough for use on common platforms (PC, etc.) while being low-level enough forno_stdones too.bevy_core_pipeline⚠thiserrorfrombevy_core_pipeline#15775Blocked by
bevy_render.bevy_dev_tools⚠Blocked by
bevy_render.bevy_dylib⚠Unfamiliar with the dynamic linking this crate provides. I don't see any reason why it couldn't be supported in
no_std, but I would definitely require an SME to assist with getting it working.bevy_encase_derive⚠Exclusively used with
encase, which is a part of the rendering side of Bevy.bevy_gilrs⚠thiserrorfrombevy_gilrs#15773Built around
gilrswhich does not currently have anyno_stdsupport. There might be a way to upstreamno_stdsupport by relying on something likeSDL, but I'm not familiar enough with the project to make a fair assessment on the viability here.bevy_gizmos⚠Blocked by
bevy_render.bevy_gltf⚠thiserrorfrombevy_gltf#15772Blocked by
bevy_render. It may make sense to find a way to break this dependency, sincegLTFcan be used independently ofwgpu(e.g., with a user-created OpenGL renderer backend), but this would need an SME for sure.bevy_pbr⚠thiserrorfrombevy_pbr#15767Blocked by
bevy_renderandwgpu. Without support for WGSL shaders there's no real point in having this crate supported inno_std.bevy_render⚠thiserrorfrombevy_render#15765Massive crate very deeply integrated with
wgpu, which is not juststdreliant, but also platform dependent too. I don't think it will ever make sense to have ano_stdbevy_render. Maybe could have value in splitting out some abstractions, but I don't know.bevy_sprite⚠thiserrorfrombevy_sprite#15763Blocked on
bevy_render.bevy_text⚠thiserrorfrombevy_text#15762Blocked on
bevy_render.bevy_ui⚠thiserrorfrombevy_ui#15760Blocked on
bevy_render.bevy_winit⚠Blocked on
winit. Likely couldn't be madeno_stdupstream either since it's entirely platform dependent.General Notes
thiserrorNote: this is now outdated, as
thiserrorversion 2 includesno_stdsupport and is now publicly available.thiserroris currently not available in ano_stdform due to its use of the::std::error::Errorpath forError(which it continues to use for MSRV backwards compatibility). There is a PR to addno_stdsupport tothiserrorwhich preserves that MSRV requirement, but it's unclear if/when that will be merged and released.One alternative is to link against the PR instead of the published version of
thiserror:Another alternative is to switch to using
derive_more. This would require adding explicit calls toderive(From, Display)as well, which adds to the noise. Additionally, it isn't already in the dependency tree, so its inclusion may be contentious.Due to delays in
thiserror'sno_stdsupport, we have decided to usederive_more.portable-atomicCertain platforms, such as the Raspberry Pi Pico, could run Bevy once
no_stdsupport is added, but can't due to Bevy's use of certain atomic features. To work around this issue, Bevy should employportable-atomicand its siblingportable-atomic-util. These crates provide suitable replacements for the variousAtomicXtypes andArc.This adds
cfg(...)burden to the project, but would be limited in scope tobevy_ecsandbevy_tasks(the largest users of atomic types), at least initially. Additionally, there is issue with coercion sinceportable_atomic_util::Arcis a 3rd party smart-pointer, so you cannot, for example, create anArc<dyn T>directly from anArc<impl T>. There is a simple workaround, but at a small performance cost for unsized types. However, this will be resolved once #18598 stabilises.Platform Support
Being
no_stdis necessary for certain platforms, but it is not always sufficient. Below is a table of platforms that I have tested:x86_64-unknown-uefiueficrate.thumbv4t-none-eabitracingtolog, and usingportable_atomicsis sufficient to make this platform compile.aarch64-nintendo-switch-freestandingcargo nxon real hardware or an emulator to confirm it actually works.mipsel-sony-psxtracingtolog, and usingportable_atomicsis sufficient to make this platform compile.msp430-none-elfzerocopy.thumbv7em-none-eabihffixedbitsetto disabled SIMD. Could potentially be fixed from within Bevy without the patch though.thumbv6m-none-eabiportable_atomicswithin Bevy, since the Pico doesn't support the atomic CAS instructions required.I have a prototype of
no_stdcompatible Bevy available on this branch. It's not being actively maintained, as it is a proof of concept for upstreamno_stdsupport (use at your own risk, etc.). However, if anyone has a particular platform they'd like to use Bevy on, please feel free to test using this branch and let me know what kind of compatibility you have. In general:allocandcoreavailable.bevy_app,bevy_ecs,bevy_utils, andbevy_tasksare compatible in this branch, and must be imported directly (e.g., you can'tuse bevy;, insteaduse bevy_app;). Additionally, you must disable default features forno_stdcompatibility.bevy_ecs. For further information, see [Merged by Bors] - Fail to compile on 16-bit platforms #4736.Having an
stdFeatureI've posted a more detailed write-up here. But as a succinct warning:
no_stdcrates should unconditionally be#[no_std]to ensure consistent implicit prelude.These findings are acted upon in #17086.
Building for Web using
wasm32v1-noneAs of Rust 1.84,
wasm32v1-nonehas been stabilised as a tier 2 (no_std) target. This is notable compared to the existingwasm32-unknown-unknowntarget in that it doesn't enable new proposals as they're stabilised. This massively improves browser compatibility at the expense of some performance and functionality.As stated, this new target is strictly
no_std. This avoids the stubbed-out version ofstdthatwasm32-unknown-unknownhas, which panics when attempting to use unsupported APIs. This has the interesting side-effect of motivating previously disinterested parties into supportingno_std. A highly relevant example of this iswgpu. Withwgpupotentially gainingno_stdsupport, the possibility ofbevy_renderand all of its downstream crates becomingno_stdcompatible themselves goes from an outright impossibility to a potentially desirable mainstream feature.Footnotes
bevy_corehas been removed, effectively resolving itsno_stdcompatibility. ↩bevy_hierarchyhas been removed since its port. ↩