From c7de4abcadc2d21a3bdb5021030b45c6abf06f1e Mon Sep 17 00:00:00 2001 From: Hennadii Chernyshchyk Date: Wed, 17 Dec 2025 21:10:19 +0200 Subject: [PATCH] Add `no_std` support to `bevy_log` Currently requires a new release of `tracing-subscriber`. Once released, 2 lines needs to be uncommented in `Cargo.toml`, see `TODO`. --- Cargo.toml | 5 -- crates/bevy_animation/Cargo.toml | 12 +++++ crates/bevy_dylib/src/lib.rs | 2 + crates/bevy_gltf/Cargo.toml | 15 ++++++ crates/bevy_internal/Cargo.toml | 8 +-- crates/bevy_internal/src/default_plugins.rs | 1 - crates/bevy_internal/src/lib.rs | 1 - crates/bevy_internal/src/prelude.rs | 10 ++-- crates/bevy_log/Cargo.toml | 60 ++++++++++++++++----- crates/bevy_log/src/android_tracing.rs | 2 +- crates/bevy_log/src/lib.rs | 21 ++++++-- crates/bevy_text/Cargo.toml | 15 ++++++ crates/bevy_transform/Cargo.toml | 4 +- crates/bevy_transform/src/systems.rs | 1 - crates/bevy_winit/Cargo.toml | 3 ++ docs/cargo_features.md | 1 - 16 files changed, 120 insertions(+), 41 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 7dda86c8f1418..e64e7533478a4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -183,7 +183,6 @@ default_app = [ "async_executor", "bevy_asset", "bevy_input_focus", - "bevy_log", "bevy_state", "bevy_window", "custom_cursor", @@ -392,9 +391,6 @@ pan_camera = ["bevy_internal/pan_camera"] # Enable the Bevy Remote Protocol bevy_remote = ["bevy_internal/bevy_remote"] -# Enable integration with `tracing` and `log` -bevy_log = ["bevy_internal/bevy_log"] - # Enable input focus subsystem bevy_input_focus = ["bevy_internal/bevy_input_focus"] @@ -1737,7 +1733,6 @@ wasm = true name = "headless" path = "examples/app/headless.rs" doc-scrape-examples = true -required-features = ["bevy_log"] [package.metadata.example.headless] name = "Headless" diff --git a/crates/bevy_animation/Cargo.toml b/crates/bevy_animation/Cargo.toml index 047609fd84f07..3eaa8faa1575a 100644 --- a/crates/bevy_animation/Cargo.toml +++ b/crates/bevy_animation/Cargo.toml @@ -48,6 +48,18 @@ tracing = { version = "0.1", default-features = false, features = ["std"] } [target.'cfg(target_arch = "wasm32")'.dependencies] # TODO: Assuming all wasm builds are for the browser. Require `no_std` support to break assumption. uuid = { version = "1.13.1", default-features = false, features = ["js"] } +bevy_log = { path = "../bevy_log", version = "0.18.0-dev", default-features = false, features = [ + "web", +] } +bevy_app = { path = "../bevy_app", version = "0.18.0-dev", default-features = false, features = [ + "web", +] } +bevy_platform = { path = "../bevy_platform", version = "0.18.0-dev", default-features = false, features = [ + "web", +] } +bevy_reflect = { path = "../bevy_reflect", version = "0.18.0-dev", default-features = false, features = [ + "web", +] } [lints] workspace = true diff --git a/crates/bevy_dylib/src/lib.rs b/crates/bevy_dylib/src/lib.rs index 941e973ee22ab..c6ab7e22d5403 100644 --- a/crates/bevy_dylib/src/lib.rs +++ b/crates/bevy_dylib/src/lib.rs @@ -53,6 +53,8 @@ //! use bevy_dylib; //! ``` +#![no_std] + // Force linking of the main bevy crate #[expect( unused_imports, diff --git a/crates/bevy_gltf/Cargo.toml b/crates/bevy_gltf/Cargo.toml index 34e1c56b73d98..38fe7fa1f143e 100644 --- a/crates/bevy_gltf/Cargo.toml +++ b/crates/bevy_gltf/Cargo.toml @@ -69,6 +69,21 @@ tracing = { version = "0.1", default-features = false, features = ["std"] } [dev-dependencies] bevy_log = { path = "../bevy_log", version = "0.18.0-dev" } +[target.'cfg(target_arch = "wasm32")'.dependencies] +# TODO: Assuming all wasm builds are for the browser. Require `no_std` support to break assumption. +bevy_log = { path = "../bevy_log", version = "0.18.0-dev", default-features = false, features = [ + "web", +] } +bevy_app = { path = "../bevy_app", version = "0.18.0-dev", default-features = false, features = [ + "web", +] } +bevy_platform = { path = "../bevy_platform", version = "0.18.0-dev", default-features = false, features = [ + "web", +] } +bevy_reflect = { path = "../bevy_reflect", version = "0.18.0-dev", default-features = false, features = [ + "web", +] } + [lints] workspace = true diff --git a/crates/bevy_internal/Cargo.toml b/crates/bevy_internal/Cargo.toml index 40993d65c9e7a..b8e9cd4b86923 100644 --- a/crates/bevy_internal/Cargo.toml +++ b/crates/bevy_internal/Cargo.toml @@ -379,6 +379,7 @@ std = [ "bevy_ecs/std", "bevy_input/std", "bevy_input_focus?/std", + "bevy_log/std", "bevy_math/std", "bevy_platform/std", "bevy_reflect/std", @@ -395,6 +396,7 @@ critical-section = [ "bevy_app/critical-section", "bevy_diagnostic/critical-section", "bevy_ecs/critical-section", + "bevy_log/critical-section", "bevy_input/critical-section", "bevy_input_focus?/critical-section", "bevy_platform/critical-section", @@ -424,7 +426,7 @@ async_executor = [ # Enables use of browser APIs. # Note this is currently only applicable on `wasm32` architectures. -web = ["bevy_app/web", "bevy_platform/web", "bevy_reflect/web"] +web = ["bevy_app/web", "bevy_log/web", "bevy_platform/web", "bevy_reflect/web"] # Input sources. mouse = ["bevy_input/mouse"] @@ -452,6 +454,7 @@ bevy_ecs = { path = "../bevy_ecs", version = "0.18.0-dev", default-features = fa bevy_input = { path = "../bevy_input", version = "0.18.0-dev", default-features = false, features = [ "bevy_reflect", ] } +bevy_log = { path = "../bevy_log", version = "0.18.0-dev", default-features = false } bevy_math = { path = "../bevy_math", version = "0.18.0-dev", default-features = false, features = [ "bevy_reflect", "nostd-libm", @@ -473,9 +476,6 @@ bevy_transform = { path = "../bevy_transform", version = "0.18.0-dev", default-f bevy_utils = { path = "../bevy_utils", version = "0.18.0-dev", default-features = false } bevy_tasks = { path = "../bevy_tasks", version = "0.18.0-dev", default-features = false } -# bevy (std required) -bevy_log = { path = "../bevy_log", version = "0.18.0-dev", optional = true } - # bevy (optional) bevy_a11y = { path = "../bevy_a11y", optional = true, version = "0.18.0-dev", features = [ "bevy_reflect", diff --git a/crates/bevy_internal/src/default_plugins.rs b/crates/bevy_internal/src/default_plugins.rs index f6b00d36017c6..7240aa8fb90c2 100644 --- a/crates/bevy_internal/src/default_plugins.rs +++ b/crates/bevy_internal/src/default_plugins.rs @@ -4,7 +4,6 @@ plugin_group! { /// This plugin group will add all the default plugins for a *Bevy* application: pub struct DefaultPlugins { bevy_app:::PanicHandlerPlugin, - #[cfg(feature = "bevy_log")] bevy_log:::LogPlugin, bevy_app:::TaskPoolPlugin, bevy_diagnostic:::FrameCountPlugin, diff --git a/crates/bevy_internal/src/lib.rs b/crates/bevy_internal/src/lib.rs index d1dab307fa7b6..873705a0aa488 100644 --- a/crates/bevy_internal/src/lib.rs +++ b/crates/bevy_internal/src/lib.rs @@ -56,7 +56,6 @@ pub use bevy_input as input; pub use bevy_input_focus as input_focus; #[cfg(feature = "bevy_light")] pub use bevy_light as light; -#[cfg(feature = "bevy_log")] pub use bevy_log as log; pub use bevy_math as math; #[cfg(feature = "bevy_mesh")] diff --git a/crates/bevy_internal/src/prelude.rs b/crates/bevy_internal/src/prelude.rs index ea4a306d0a6d6..bb168b57dbf27 100644 --- a/crates/bevy_internal/src/prelude.rs +++ b/crates/bevy_internal/src/prelude.rs @@ -1,14 +1,10 @@ #[doc(hidden)] pub use crate::{ - app::prelude::*, ecs::prelude::*, input::prelude::*, math::prelude::*, platform::prelude::*, - reflect::prelude::*, time::prelude::*, transform::prelude::*, utils::prelude::*, - DefaultPlugins, MinimalPlugins, + app::prelude::*, ecs::prelude::*, input::prelude::*, log::prelude::*, math::prelude::*, + platform::prelude::*, reflect::prelude::*, time::prelude::*, transform::prelude::*, + utils::prelude::*, DefaultPlugins, MinimalPlugins, }; -#[doc(hidden)] -#[cfg(feature = "bevy_log")] -pub use crate::log::prelude::*; - #[doc(hidden)] #[cfg(feature = "bevy_window")] pub use crate::window::prelude::*; diff --git a/crates/bevy_log/Cargo.toml b/crates/bevy_log/Cargo.toml index eccc424242ec4..0822cf493c942 100644 --- a/crates/bevy_log/Cargo.toml +++ b/crates/bevy_log/Cargo.toml @@ -9,25 +9,55 @@ license = "MIT OR Apache-2.0" keywords = ["bevy"] [features] -trace = ["tracing-error"] -trace_tracy_memory = ["dep:tracy-client"] +default = ["std"] +trace = ["std", "dep:tracing-error"] +trace_tracy_memory = ["std", "dep:tracy-client"] + +# Platform Compatibility + +# Allows access to the `std` crate. Enabling this feature will prevent compilation +# on `no_std` targets, but provides access to certain additional features on +# supported platforms. +std = [ + "bevy_app/std", + "bevy_utils/std", + "bevy_ecs/std", + "tracing/std", + "tracing-subscriber/std", + "tracing-log/std", +] + +## `critical-section` provides the building blocks for synchronization primitives +## on all platforms, including `no_std`. +critical-section = [ + # TODO: wait for `tracing-subscriber` release + # "tracing-subscriber/critical-section" +] + +# Enables use of browser APIs. +# Note this is currently only applicable on `wasm32` architectures. +web = ["bevy_app/web", "dep:tracing-wasm"] [dependencies] # bevy -bevy_app = { path = "../bevy_app", version = "0.18.0-dev" } -bevy_utils = { path = "../bevy_utils", version = "0.18.0-dev" } -bevy_platform = { path = "../bevy_platform", version = "0.18.0-dev" } -bevy_ecs = { path = "../bevy_ecs", version = "0.18.0-dev" } +bevy_app = { path = "../bevy_app", version = "0.18.0-dev", default-features = false } +bevy_utils = { path = "../bevy_utils", version = "0.18.0-dev", default-features = false } +bevy_platform = { path = "../bevy_platform", version = "0.18.0-dev", default-features = false } +bevy_ecs = { path = "../bevy_ecs", version = "0.18.0-dev", default-features = false } # other -tracing-subscriber = { version = "0.3.20", features = [ +tracing-subscriber = { version = "0.3.20", default-features = false, features = [ "registry", "env-filter", + "fmt", + "tracing-log", ] } tracing-chrome = { version = "0.7.0", optional = true } -tracing-log = "0.2.0" +tracing-log = { version = "0.2.0", default-features = false, features = [ + "log-tracer", +] } tracing-error = { version = "0.2.0", optional = true } -tracing = { version = "0.1", default-features = false, features = ["std"] } +tracing = { version = "0.1", default-features = false } # Tracy dependency compatibility table: # https://github.com/nagisa/rust_tracy_client @@ -38,15 +68,17 @@ tracy-client = { version = "0.18.3", optional = true } android_log-sys = "0.3.0" [target.'cfg(target_arch = "wasm32")'.dependencies] -tracing-wasm = "0.2.1" -# TODO: Assuming all wasm builds are for the browser. Require `no_std` support to break assumption. -bevy_app = { path = "../bevy_app", version = "0.18.0-dev", default-features = false, features = [ - "web", -] } +tracing-wasm = { version = "0.2.1", optional = true } [target.'cfg(target_os = "ios")'.dependencies] tracing-oslog = "0.3" +[target.'cfg(not(all(target_has_atomic = "8", target_has_atomic = "16", target_has_atomic = "32", target_has_atomic = "64", target_has_atomic = "ptr")))'.dependencies] +tracing-subscriber = { version = "0.3.1", default-features = false, features = [ + # TODO: wait for `tracing-subscriber` release + # "portable-atomic", +] } + [lints] workspace = true diff --git a/crates/bevy_log/src/android_tracing.rs b/crates/bevy_log/src/android_tracing.rs index ba0b3b7a27a38..fc9931607d401 100644 --- a/crates/bevy_log/src/android_tracing.rs +++ b/crates/bevy_log/src/android_tracing.rs @@ -1,4 +1,4 @@ -use alloc::ffi::CString; +use alloc::{ffi::CString, format, string::String, vec::Vec}; use core::fmt::{Debug, Write}; use tracing::{ field::Field, diff --git a/crates/bevy_log/src/lib.rs b/crates/bevy_log/src/lib.rs index 72163f2516075..d9bf6f9fe4ec9 100644 --- a/crates/bevy_log/src/lib.rs +++ b/crates/bevy_log/src/lib.rs @@ -15,10 +15,11 @@ //! //! For more fine-tuned control over logging behavior, set up the [`LogPlugin`] or //! `DefaultPlugins` during app initialization. +#![no_std] extern crate alloc; - -use core::error::Error; +#[cfg(feature = "std")] +extern crate std; #[cfg(target_os = "android")] mod android_tracing; @@ -52,6 +53,15 @@ pub use tracing::{ }; pub use tracing_subscriber; +use alloc::{ + boxed::Box, + format, + string::{String, ToString}, +}; +use core::error::Error; +#[cfg(feature = "std")] +use std::eprintln; + use bevy_app::{App, Plugin}; use tracing_log::LogTracer; use tracing_subscriber::{ @@ -323,9 +333,10 @@ impl Plugin for LogPlugin { _ = from_env_error .source() .and_then(|source| source.downcast_ref::()) - .map(|parse_err| { + .inspect(|_parse_err| { // we cannot use the `error!` macro here because the logger is not ready yet. - eprintln!("LogPlugin failed to parse filter from env: {parse_err}"); + #[cfg(feature = "std")] + eprintln!("LogPlugin failed to parse filter from env: {_parse_err}"); }); Ok::(EnvFilter::builder().parse_lossy(&default_filter)) @@ -365,6 +376,7 @@ impl Plugin for LogPlugin { #[cfg(feature = "tracing-tracy")] let tracy_layer = tracing_tracy::TracyLayer::default(); + #[cfg(feature = "std")] let fmt_layer = (self.fmt_layer)(app).unwrap_or_else(|| { // note: the implementation of `Default` reads from the env var NO_COLOR // to decide whether to use ANSI color codes, which is common convention @@ -380,6 +392,7 @@ impl Plugin for LogPlugin { meta.fields().field("tracy.frame_mark").is_none() })); + #[cfg(any(feature = "std", feature = "tracing-tracy"))] let subscriber = subscriber.with(fmt_layer); #[cfg(all(feature = "tracing-chrome", not(target_os = "android")))] diff --git a/crates/bevy_text/Cargo.toml b/crates/bevy_text/Cargo.toml index 9e153138b989b..0224a07888ffb 100644 --- a/crates/bevy_text/Cargo.toml +++ b/crates/bevy_text/Cargo.toml @@ -37,6 +37,21 @@ smallvec = { version = "1", default-features = false } sys-locale = "0.3.0" tracing = { version = "0.1", default-features = false, features = ["std"] } +[target.'cfg(target_arch = "wasm32")'.dependencies] +# TODO: Assuming all wasm builds are for the browser. Require `no_std` support to break assumption. +bevy_log = { path = "../bevy_log", version = "0.18.0-dev", default-features = false, features = [ + "web", +] } +bevy_app = { path = "../bevy_app", version = "0.18.0-dev", default-features = false, features = [ + "web", +] } +bevy_platform = { path = "../bevy_platform", version = "0.18.0-dev", default-features = false, features = [ + "web", +] } +bevy_reflect = { path = "../bevy_reflect", version = "0.18.0-dev", default-features = false, features = [ + "web", +] } + [lints] workspace = true diff --git a/crates/bevy_transform/Cargo.toml b/crates/bevy_transform/Cargo.toml index 42173c0f1776b..43b013e8e49c1 100644 --- a/crates/bevy_transform/Cargo.toml +++ b/crates/bevy_transform/Cargo.toml @@ -41,7 +41,7 @@ default = ["std", "bevy-support", "bevy_reflect", "async_executor"] ## systems for transform propagation and more. ## This exists because it allows opting out of all of this, leaving only a bare-bones transform struct, ## which enables users to depend on that without needing the larger Bevy dependency tree. -bevy-support = ["alloc", "dep:bevy_app", "dep:bevy_ecs"] +bevy-support = ["alloc", "dep:bevy_app", "dep:bevy_log", "dep:bevy_ecs"] ## Adds serialization support through `serde`. serialize = ["dep:serde", "bevy_math/serialize"] @@ -69,7 +69,7 @@ async_executor = ["std", "bevy_tasks/async_executor"] std = [ "alloc", "bevy_app?/std", - "bevy_log", + "bevy_log?/std", "bevy_ecs?/std", "bevy_math/std", "bevy_reflect?/std", diff --git a/crates/bevy_transform/src/systems.rs b/crates/bevy_transform/src/systems.rs index 34366b1b3ce25..3d2716bf2e482 100644 --- a/crates/bevy_transform/src/systems.rs +++ b/crates/bevy_transform/src/systems.rs @@ -332,7 +332,6 @@ mod parallel { /// children to the queue once it has propagated their [`GlobalTransform`]. #[inline] fn propagation_worker(queue: &WorkQueue, nodes: &NodeQuery) { - #[cfg(feature = "std")] let _span = bevy_log::info_span!("transform propagation worker").entered(); let mut outbox = queue.local_queue.borrow_local_mut(); diff --git a/crates/bevy_winit/Cargo.toml b/crates/bevy_winit/Cargo.toml index 6855cfce2314f..a502c95b4d712 100644 --- a/crates/bevy_winit/Cargo.toml +++ b/crates/bevy_winit/Cargo.toml @@ -89,6 +89,9 @@ bevy_platform = { path = "../bevy_platform", version = "0.18.0-dev", default-fea bevy_reflect = { path = "../bevy_reflect", version = "0.18.0-dev", default-features = false, features = [ "web", ] } +bevy_log = { path = "../bevy_log", version = "0.18.0-dev", default-features = false, features = [ + "web", +] } [lints] workspace = true diff --git a/docs/cargo_features.md b/docs/cargo_features.md index 231038b9e1f31..170f92ddf45d0 100644 --- a/docs/cargo_features.md +++ b/docs/cargo_features.md @@ -83,7 +83,6 @@ This is the complete `bevy` cargo feature list, without "profiles" or "collectio |bevy_image|Load and access image data. Usually added by an image format| |bevy_input_focus|Enable input focus subsystem| |bevy_light|Provides light types such as point lights, directional lights, spotlights.| -|bevy_log|Enable integration with `tracing` and `log`| |bevy_mesh|Provides a mesh format and some primitive meshing routines.| |bevy_mikktspace|Provides vertex tangent generation for use with bevy_mesh.| |bevy_pbr|Adds PBR rendering|