Skip to content

Commit cc69fdd

Browse files
Add no_std support to bevy (#17955)
# Objective - Fixes #15460 (will open new issues for further `no_std` efforts) - Supersedes #17715 ## Solution - Threaded in new features as required - Made certain crates optional but default enabled - Removed `compile-check-no-std` from internal `ci` tool since GitHub CI can now simply check `bevy` itself now - Added CI task to check `bevy` on `thumbv6m-none-eabi` to ensure `portable-atomic` support is still valid [^1] [^1]: This may be controversial, since it could be interpreted as implying Bevy will maintain support for `thumbv6m-none-eabi` going forward. In reality, just like `x86_64-unknown-none`, this is a [canary](https://en.wiktionary.org/wiki/canary_in_a_coal_mine) target to make it clear when `portable-atomic` no longer works as intended (fixing atomic support on atomically challenged platforms). If a PR comes through and makes supporting this class of platforms impossible, then this CI task can be removed. I however wager this won't be a problem. ## Testing - CI --- ## Release Notes Bevy now has support for `no_std` directly from the `bevy` crate. Users can disable default features and enable a new `default_no_std` feature instead, allowing `bevy` to be used in `no_std` applications and libraries. ```toml # Bevy for `no_std` platforms bevy = { version = "0.16", default-features = false, features = ["default_no_std"] } ``` `default_no_std` enables certain required features, such as `libm` and `critical-section`, and as many optional crates as possible (currently just `bevy_state`). For atomically-challenged platforms such as the Raspberry Pi Pico, `portable-atomic` will be used automatically. For library authors, we recommend depending on `bevy` with `default-features = false` to allow `std` and `no_std` users to both depend on your crate. Here are some recommended features a library crate may want to expose: ```toml [features] # Most users will be on a platform which has `std` and can use the more-powerful `async_executor`. default = ["std", "async_executor"] # Features for typical platforms. std = ["bevy/std"] async_executor = ["bevy/async_executor"] # Features for `no_std` platforms. libm = ["bevy/libm"] critical-section = ["bevy/critical-section"] [dependencies] # We disable default features to ensure we don't accidentally enable `std` on `no_std` targets, for example. bevy = { version = "0.16", default-features = false } ``` While this is verbose, it gives the maximum control to end-users to decide how they wish to use Bevy on their platform. We encourage library authors to experiment with `no_std` support. For libraries relying exclusively on `bevy` and no other dependencies, it may be as simple as adding `#![no_std]` to your `lib.rs` and exposing features as above! Bevy can also provide many `std` types, such as `HashMap`, `Mutex`, and `Instant` on all platforms. See `bevy::platform_support` for details on what's available out of the box! ## Migration Guide - If you were previously relying on `bevy` with default features disabled, you may need to enable the `std` and `async_executor` features. - `bevy_reflect` has had its `bevy` feature removed. If you were relying on this feature, simply enable `smallvec` and `smol_str` instead. --------- Co-authored-by: Alice Cecile <[email protected]>
1 parent 5bc1d68 commit cc69fdd

File tree

41 files changed

+903
-363
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+903
-363
lines changed

.github/workflows/ci.yml

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,31 @@ jobs:
151151
- name: Install Linux dependencies
152152
uses: ./.github/actions/install-linux-deps
153153
- name: Check Compile
154-
run: cargo run -p ci -- compile-check-no-std
154+
run: cargo check -p bevy --no-default-features --features default_no_std --target x86_64-unknown-none
155+
check-compiles-no-std-portable-atomic:
156+
runs-on: ubuntu-latest
157+
timeout-minutes: 30
158+
needs: ci
159+
steps:
160+
- uses: actions/checkout@v4
161+
- uses: actions/cache@v4
162+
with:
163+
path: |
164+
~/.cargo/bin/
165+
~/.cargo/registry/index/
166+
~/.cargo/registry/cache/
167+
~/.cargo/git/db/
168+
target/
169+
crates/bevy_ecs_compile_fail_tests/target/
170+
crates/bevy_reflect_compile_fail_tests/target/
171+
key: ${{ runner.os }}-cargo-check-compiles-no-std-portable-atomic-${{ hashFiles('**/Cargo.toml') }}
172+
- uses: dtolnay/rust-toolchain@stable
173+
with:
174+
targets: thumbv6m-none-eabi
175+
- name: Install Linux dependencies
176+
uses: ./.github/actions/install-linux-deps
177+
- name: Check Compile
178+
run: cargo check -p bevy --no-default-features --features default_no_std --target thumbv6m-none-eabi
155179

156180
build-wasm:
157181
runs-on: ubuntu-latest

Cargo.toml

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,8 @@ unused_qualifications = "warn"
120120

121121
[features]
122122
default = [
123+
"std",
124+
"async_executor",
123125
"android-game-activity",
124126
"android_shared_stdcxx",
125127
"animation",
@@ -130,6 +132,8 @@ default = [
130132
"bevy_gilrs",
131133
"bevy_gizmos",
132134
"bevy_gltf",
135+
"bevy_input_focus",
136+
"bevy_log",
133137
"bevy_mesh_picking_backend",
134138
"bevy_pbr",
135139
"bevy_picking",
@@ -156,6 +160,9 @@ default = [
156160
"x11",
157161
]
158162

163+
# Recommended defaults for no_std applications
164+
default_no_std = ["libm", "critical-section", "bevy_color", "bevy_state"]
165+
159166
# Provides an implementation for picking meshes
160167
bevy_mesh_picking_backend = [
161168
"bevy_picking",
@@ -263,6 +270,12 @@ bevy_dev_tools = ["bevy_internal/bevy_dev_tools"]
263270
# Enable the Bevy Remote Protocol
264271
bevy_remote = ["bevy_internal/bevy_remote"]
265272

273+
# Enable integration with `tracing` and `log`
274+
bevy_log = ["bevy_internal/bevy_log"]
275+
276+
# Enable input focus subsystem
277+
bevy_input_focus = ["bevy_internal/bevy_input_focus"]
278+
266279
# Enable passthrough loading for SPIR-V shaders (Only supported on Vulkan, shader capabilities and extensions must agree with the platform implementation)
267280
spirv_shader_passthrough = ["bevy_internal/spirv_shader_passthrough"]
268281

@@ -488,6 +501,18 @@ custom_cursor = ["bevy_internal/custom_cursor"]
488501
# Experimental support for nodes that are ignored for UI layouting
489502
ghost_nodes = ["bevy_internal/ghost_nodes"]
490503

504+
# Uses `async-executor` as a task execution backend.
505+
async_executor = ["std", "bevy_internal/async_executor"]
506+
507+
# Allows access to the `std` crate.
508+
std = ["bevy_internal/std"]
509+
510+
# `critical-section` provides the building blocks for synchronization primitives on all platforms, including `no_std`.
511+
critical-section = ["bevy_internal/critical-section"]
512+
513+
# Uses the `libm` maths library instead of the one provided in `std` and `core`.
514+
libm = ["bevy_internal/libm"]
515+
491516
[dependencies]
492517
bevy_internal = { path = "crates/bevy_internal", version = "0.16.0-dev", default-features = false }
493518
tracing = { version = "0.1", default-features = false, optional = true }

crates/bevy_animation/Cargo.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ bevy_derive = { path = "../bevy_derive", version = "0.16.0-dev" }
1717
bevy_log = { path = "../bevy_log", version = "0.16.0-dev" }
1818
bevy_math = { path = "../bevy_math", version = "0.16.0-dev" }
1919
bevy_reflect = { path = "../bevy_reflect", version = "0.16.0-dev", features = [
20-
"bevy",
2120
"petgraph",
2221
] }
2322
bevy_render = { path = "../bevy_render", version = "0.16.0-dev" }

crates/bevy_app/Cargo.toml

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,7 @@ license = "MIT OR Apache-2.0"
99
keywords = ["bevy"]
1010

1111
[features]
12-
default = [
13-
"std",
14-
"bevy_reflect",
15-
"bevy_tasks",
16-
"bevy_ecs/default",
17-
"error_panic_hook",
18-
]
12+
default = ["std", "bevy_reflect", "bevy_ecs/default", "error_panic_hook"]
1913

2014
# Functionality
2115

@@ -29,9 +23,6 @@ reflect_functions = [
2923
"bevy_ecs/reflect_functions",
3024
]
3125

32-
## Adds support for running async background tasks
33-
bevy_tasks = ["dep:bevy_tasks"]
34-
3526
# Debugging Features
3627

3728
## Enables `tracing` integration, allowing spans and other metrics to be reported
@@ -57,14 +48,14 @@ std = [
5748
"dep:ctrlc",
5849
"downcast-rs/std",
5950
"bevy_utils/std",
60-
"bevy_tasks?/std",
51+
"bevy_tasks/std",
6152
"bevy_platform_support/std",
6253
]
6354

6455
## `critical-section` provides the building blocks for synchronization primitives
6556
## on all platforms, including `no_std`.
6657
critical-section = [
67-
"bevy_tasks?/critical-section",
58+
"bevy_tasks/critical-section",
6859
"bevy_ecs/critical-section",
6960
"bevy_platform_support/critical-section",
7061
"bevy_reflect?/critical-section",
@@ -78,7 +69,7 @@ bevy_reflect = { path = "../bevy_reflect", version = "0.16.0-dev", default-featu
7869
bevy_utils = { path = "../bevy_utils", version = "0.16.0-dev", default-features = false, features = [
7970
"alloc",
8071
] }
81-
bevy_tasks = { path = "../bevy_tasks", version = "0.16.0-dev", default-features = false, optional = true }
72+
bevy_tasks = { path = "../bevy_tasks", version = "0.16.0-dev", default-features = false }
8273
bevy_platform_support = { path = "../bevy_platform_support", version = "0.16.0-dev", default-features = false }
8374

8475
# other

crates/bevy_app/src/app.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1353,7 +1353,7 @@ type RunnerFn = Box<dyn FnOnce(App) -> AppExit>;
13531353

13541354
fn run_once(mut app: App) -> AppExit {
13551355
while app.plugins_state() == PluginsState::Adding {
1356-
#[cfg(all(not(target_arch = "wasm32"), feature = "bevy_tasks"))]
1356+
#[cfg(not(target_arch = "wasm32"))]
13571357
bevy_tasks::tick_global_task_pools_on_main_thread();
13581358
}
13591359
app.finish();

crates/bevy_app/src/lib.rs

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@ mod plugin;
3030
mod plugin_group;
3131
mod schedule_runner;
3232
mod sub_app;
33-
#[cfg(feature = "bevy_tasks")]
3433
mod task_pool_plugin;
3534
#[cfg(all(any(unix, windows), feature = "std"))]
3635
mod terminal_ctrl_c_handler;
@@ -42,7 +41,6 @@ pub use plugin::*;
4241
pub use plugin_group::*;
4342
pub use schedule_runner::*;
4443
pub use sub_app::*;
45-
#[cfg(feature = "bevy_tasks")]
4644
pub use task_pool_plugin::*;
4745
#[cfg(all(any(unix, windows), feature = "std"))]
4846
pub use terminal_ctrl_c_handler::*;
@@ -60,10 +58,6 @@ pub mod prelude {
6058
RunFixedMainLoopSystem, SpawnScene, Startup, Update,
6159
},
6260
sub_app::SubApp,
63-
Plugin, PluginGroup,
61+
NonSendMarker, Plugin, PluginGroup, TaskPoolOptions, TaskPoolPlugin,
6462
};
65-
66-
#[cfg(feature = "bevy_tasks")]
67-
#[doc(hidden)]
68-
pub use crate::{NonSendMarker, TaskPoolOptions, TaskPoolPlugin};
6963
}

crates/bevy_app/src/schedule_runner.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ impl Plugin for ScheduleRunnerPlugin {
7777
let plugins_state = app.plugins_state();
7878
if plugins_state != PluginsState::Cleaned {
7979
while app.plugins_state() == PluginsState::Adding {
80-
#[cfg(all(not(target_arch = "wasm32"), feature = "bevy_tasks"))]
80+
#[cfg(not(target_arch = "wasm32"))]
8181
bevy_tasks::tick_global_task_pools_on_main_thread();
8282
}
8383
app.finish();

crates/bevy_audio/Cargo.toml

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,7 @@ bevy_app = { path = "../bevy_app", version = "0.16.0-dev" }
1414
bevy_asset = { path = "../bevy_asset", version = "0.16.0-dev" }
1515
bevy_ecs = { path = "../bevy_ecs", version = "0.16.0-dev" }
1616
bevy_math = { path = "../bevy_math", version = "0.16.0-dev" }
17-
bevy_reflect = { path = "../bevy_reflect", version = "0.16.0-dev", features = [
18-
"bevy",
19-
] }
17+
bevy_reflect = { path = "../bevy_reflect", version = "0.16.0-dev" }
2018
bevy_transform = { path = "../bevy_transform", version = "0.16.0-dev" }
2119
bevy_derive = { path = "../bevy_derive", version = "0.16.0-dev" }
2220

crates/bevy_diagnostic/Cargo.toml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ serialize = [
2626
dynamic_linking = []
2727

2828
## Adds integration with `sysinfo`.
29-
sysinfo_plugin = ["sysinfo", "dep:bevy_tasks"]
29+
sysinfo_plugin = ["sysinfo"]
3030

3131
# Platform Compatibility
3232

@@ -40,7 +40,7 @@ std = [
4040
"bevy_platform_support/std",
4141
"bevy_time/std",
4242
"bevy_utils/std",
43-
"bevy_tasks?/std",
43+
"bevy_tasks/std",
4444
]
4545

4646
## `critical-section` provides the building blocks for synchronization primitives
@@ -51,7 +51,7 @@ critical-section = [
5151
"bevy_platform_support/critical-section",
5252
"bevy_time/critical-section",
5353
"bevy_utils/critical-section",
54-
"bevy_tasks?/critical-section",
54+
"bevy_tasks/critical-section",
5555
]
5656

5757
[dependencies]
@@ -62,7 +62,7 @@ bevy_time = { path = "../bevy_time", version = "0.16.0-dev", default-features =
6262
bevy_utils = { path = "../bevy_utils", version = "0.16.0-dev", default-features = false, features = [
6363
"alloc",
6464
] }
65-
bevy_tasks = { path = "../bevy_tasks", version = "0.16.0-dev", default-features = false, optional = true }
65+
bevy_tasks = { path = "../bevy_tasks", version = "0.16.0-dev", default-features = false }
6666
bevy_platform_support = { path = "../bevy_platform_support", version = "0.16.0-dev", default-features = false, features = [
6767
"alloc",
6868
] }

crates/bevy_ecs/Cargo.toml

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -60,11 +60,7 @@ track_location = []
6060

6161
## Uses `async-executor` as a task execution backend.
6262
## This backend is incompatible with `no_std` targets.
63-
async_executor = ["dep:bevy_tasks", "std", "bevy_tasks/async_executor"]
64-
65-
## Uses `edge-executor` as a task execution backend.
66-
## Use this instead of `async-executor` if working on a `no_std` target.
67-
edge_executor = ["dep:bevy_tasks", "bevy_tasks/edge_executor"]
63+
async_executor = ["std", "bevy_tasks/async_executor"]
6864

6965
# Platform Compatibility
7066

@@ -90,7 +86,7 @@ std = [
9086
## `critical-section` provides the building blocks for synchronization primitives
9187
## on all platforms, including `no_std`.
9288
critical-section = [
93-
"bevy_tasks?/critical-section",
89+
"bevy_tasks/critical-section",
9490
"bevy_platform_support/critical-section",
9591
"bevy_reflect?/critical-section",
9692
]
@@ -100,7 +96,7 @@ bevy_ptr = { path = "../bevy_ptr", version = "0.16.0-dev" }
10096
bevy_reflect = { path = "../bevy_reflect", version = "0.16.0-dev", features = [
10197
"smallvec",
10298
], default-features = false, optional = true }
103-
bevy_tasks = { path = "../bevy_tasks", version = "0.16.0-dev", default-features = false, optional = true }
99+
bevy_tasks = { path = "../bevy_tasks", version = "0.16.0-dev", default-features = false }
104100
bevy_utils = { path = "../bevy_utils", version = "0.16.0-dev", default-features = false, features = [
105101
"alloc",
106102
] }

0 commit comments

Comments
 (0)