From 858f7fbb4c114b141d1e977182e37e653c3d902f Mon Sep 17 00:00:00 2001 From: BD103 <59022059+BD103@users.noreply.github.com> Date: Tue, 23 Apr 2024 18:00:14 -0400 Subject: [PATCH 1/4] feat!: deprecate dynamic plugins --- crates/bevy_app/src/plugin.rs | 1 + crates/bevy_derive/src/app_plugin.rs | 1 + crates/bevy_derive/src/lib.rs | 3 +++ crates/bevy_dynamic_plugin/src/loader.rs | 4 ++++ 4 files changed, 9 insertions(+) diff --git a/crates/bevy_app/src/plugin.rs b/crates/bevy_app/src/plugin.rs index d3307485fecbb..1c0548a75b998 100644 --- a/crates/bevy_app/src/plugin.rs +++ b/crates/bevy_app/src/plugin.rs @@ -124,6 +124,7 @@ impl Plugin for PlaceholderPlugin { /// It is used for dynamically loading plugins. /// /// See `bevy_dynamic_plugin/src/loader.rs#dynamically_load_plugin`. +#[deprecated(since = "0.14.0", note = "The current dynamic plugin system is unsound and will be removed in 0.15.")] pub type CreatePlugin = unsafe fn() -> *mut dyn Plugin; /// Types that represent a set of [`Plugin`]s. diff --git a/crates/bevy_derive/src/app_plugin.rs b/crates/bevy_derive/src/app_plugin.rs index 56b5d1f0450eb..bc2f5a02a9242 100644 --- a/crates/bevy_derive/src/app_plugin.rs +++ b/crates/bevy_derive/src/app_plugin.rs @@ -2,6 +2,7 @@ use proc_macro::TokenStream; use quote::quote; use syn::{parse_macro_input, DeriveInput}; +#[deprecated(since = "0.14.0", note = "The current dynamic plugin system is unsound and will be removed in 0.15.")] pub fn derive_dynamic_plugin(input: TokenStream) -> TokenStream { let ast = parse_macro_input!(input as DeriveInput); let struct_name = &ast.ident; diff --git a/crates/bevy_derive/src/lib.rs b/crates/bevy_derive/src/lib.rs index 576b26bf99c18..4ab6959b40c6d 100644 --- a/crates/bevy_derive/src/lib.rs +++ b/crates/bevy_derive/src/lib.rs @@ -19,7 +19,10 @@ use proc_macro::TokenStream; use quote::format_ident; /// Generates a dynamic plugin entry point function for the given `Plugin` type. +/// +/// This is deprecated since 0.14. The current dynamic plugin system is unsound and will be removed in 0.15. #[proc_macro_derive(DynamicPlugin)] +#[deprecated(since = "0.14.0", note = "The current dynamic plugin system is unsound and will be removed in 0.15.")] pub fn derive_dynamic_plugin(input: TokenStream) -> TokenStream { app_plugin::derive_dynamic_plugin(input) } diff --git a/crates/bevy_dynamic_plugin/src/loader.rs b/crates/bevy_dynamic_plugin/src/loader.rs index 8b6517b237244..f57e0dcbceac7 100644 --- a/crates/bevy_dynamic_plugin/src/loader.rs +++ b/crates/bevy_dynamic_plugin/src/loader.rs @@ -1,4 +1,5 @@ #![allow(unsafe_code)] +#![allow(deprecated)] use libloading::{Library, Symbol}; use std::ffi::OsStr; @@ -8,6 +9,7 @@ use bevy_app::{App, CreatePlugin, Plugin}; /// Errors that can occur when loading a dynamic plugin #[derive(Debug, Error)] +#[deprecated(since = "0.14.0", note = "The current dynamic plugin system is unsound and will be removed in 0.15.")] pub enum DynamicPluginLoadError { /// An error occurred when loading a dynamic library. #[error("cannot load library for dynamic plugin: {0}")] @@ -30,6 +32,7 @@ pub enum DynamicPluginLoadError { /// foreign code, initialization routines may be run (as well as termination routines when the /// program exits). The caller of this function is responsible for ensuring these routines are /// sound. For more information, please see the safety section of [`libloading::Library::new`]. +#[deprecated(since = "0.14.0", note = "The current dynamic plugin system is unsound and will be removed in 0.15.")] pub unsafe fn dynamically_load_plugin>( path: P, ) -> Result<(Library, Box), DynamicPluginLoadError> { @@ -51,6 +54,7 @@ pub unsafe fn dynamically_load_plugin>( } /// An extension trait for [`App`] that allows loading dynamic plugins. +#[deprecated(since = "0.14.0", note = "The current dynamic plugin system is unsound and will be removed in 0.15.")] pub trait DynamicPluginExt { /// Dynamically links a plugin at the given path, registering the plugin. /// From ca13ab0e2cb62181cfa2f6074e1abba1e932ea48 Mon Sep 17 00:00:00 2001 From: BD103 <59022059+BD103@users.noreply.github.com> Date: Tue, 23 Apr 2024 18:16:09 -0400 Subject: [PATCH 2/4] refactor: fmt --- crates/bevy_app/src/plugin.rs | 5 ++++- crates/bevy_derive/src/app_plugin.rs | 5 ++++- crates/bevy_derive/src/lib.rs | 7 +++++-- crates/bevy_dynamic_plugin/src/loader.rs | 15 ++++++++++++--- 4 files changed, 25 insertions(+), 7 deletions(-) diff --git a/crates/bevy_app/src/plugin.rs b/crates/bevy_app/src/plugin.rs index 1c0548a75b998..6b0d29a11219e 100644 --- a/crates/bevy_app/src/plugin.rs +++ b/crates/bevy_app/src/plugin.rs @@ -124,7 +124,10 @@ impl Plugin for PlaceholderPlugin { /// It is used for dynamically loading plugins. /// /// See `bevy_dynamic_plugin/src/loader.rs#dynamically_load_plugin`. -#[deprecated(since = "0.14.0", note = "The current dynamic plugin system is unsound and will be removed in 0.15.")] +#[deprecated( + since = "0.14.0", + note = "The current dynamic plugin system is unsound and will be removed in 0.15." +)] pub type CreatePlugin = unsafe fn() -> *mut dyn Plugin; /// Types that represent a set of [`Plugin`]s. diff --git a/crates/bevy_derive/src/app_plugin.rs b/crates/bevy_derive/src/app_plugin.rs index bc2f5a02a9242..108f567ac40a4 100644 --- a/crates/bevy_derive/src/app_plugin.rs +++ b/crates/bevy_derive/src/app_plugin.rs @@ -2,7 +2,10 @@ use proc_macro::TokenStream; use quote::quote; use syn::{parse_macro_input, DeriveInput}; -#[deprecated(since = "0.14.0", note = "The current dynamic plugin system is unsound and will be removed in 0.15.")] +#[deprecated( + since = "0.14.0", + note = "The current dynamic plugin system is unsound and will be removed in 0.15." +)] pub fn derive_dynamic_plugin(input: TokenStream) -> TokenStream { let ast = parse_macro_input!(input as DeriveInput); let struct_name = &ast.ident; diff --git a/crates/bevy_derive/src/lib.rs b/crates/bevy_derive/src/lib.rs index 4ab6959b40c6d..0a9d221c1244f 100644 --- a/crates/bevy_derive/src/lib.rs +++ b/crates/bevy_derive/src/lib.rs @@ -19,10 +19,13 @@ use proc_macro::TokenStream; use quote::format_ident; /// Generates a dynamic plugin entry point function for the given `Plugin` type. -/// +/// /// This is deprecated since 0.14. The current dynamic plugin system is unsound and will be removed in 0.15. #[proc_macro_derive(DynamicPlugin)] -#[deprecated(since = "0.14.0", note = "The current dynamic plugin system is unsound and will be removed in 0.15.")] +#[deprecated( + since = "0.14.0", + note = "The current dynamic plugin system is unsound and will be removed in 0.15." +)] pub fn derive_dynamic_plugin(input: TokenStream) -> TokenStream { app_plugin::derive_dynamic_plugin(input) } diff --git a/crates/bevy_dynamic_plugin/src/loader.rs b/crates/bevy_dynamic_plugin/src/loader.rs index f57e0dcbceac7..09c65d62730e2 100644 --- a/crates/bevy_dynamic_plugin/src/loader.rs +++ b/crates/bevy_dynamic_plugin/src/loader.rs @@ -9,7 +9,10 @@ use bevy_app::{App, CreatePlugin, Plugin}; /// Errors that can occur when loading a dynamic plugin #[derive(Debug, Error)] -#[deprecated(since = "0.14.0", note = "The current dynamic plugin system is unsound and will be removed in 0.15.")] +#[deprecated( + since = "0.14.0", + note = "The current dynamic plugin system is unsound and will be removed in 0.15." +)] pub enum DynamicPluginLoadError { /// An error occurred when loading a dynamic library. #[error("cannot load library for dynamic plugin: {0}")] @@ -32,7 +35,10 @@ pub enum DynamicPluginLoadError { /// foreign code, initialization routines may be run (as well as termination routines when the /// program exits). The caller of this function is responsible for ensuring these routines are /// sound. For more information, please see the safety section of [`libloading::Library::new`]. -#[deprecated(since = "0.14.0", note = "The current dynamic plugin system is unsound and will be removed in 0.15.")] +#[deprecated( + since = "0.14.0", + note = "The current dynamic plugin system is unsound and will be removed in 0.15." +)] pub unsafe fn dynamically_load_plugin>( path: P, ) -> Result<(Library, Box), DynamicPluginLoadError> { @@ -54,7 +60,10 @@ pub unsafe fn dynamically_load_plugin>( } /// An extension trait for [`App`] that allows loading dynamic plugins. -#[deprecated(since = "0.14.0", note = "The current dynamic plugin system is unsound and will be removed in 0.15.")] +#[deprecated( + since = "0.14.0", + note = "The current dynamic plugin system is unsound and will be removed in 0.15." +)] pub trait DynamicPluginExt { /// Dynamically links a plugin at the given path, registering the plugin. /// From 9b6ef6f2c50ec56cb757639fff13f04a4a26c404 Mon Sep 17 00:00:00 2001 From: BD103 <59022059+BD103@users.noreply.github.com> Date: Tue, 23 Apr 2024 18:17:14 -0400 Subject: [PATCH 3/4] fix: allow use of deprecated derive --- crates/bevy_derive/src/lib.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/crates/bevy_derive/src/lib.rs b/crates/bevy_derive/src/lib.rs index 0a9d221c1244f..19fb1b71c7cc3 100644 --- a/crates/bevy_derive/src/lib.rs +++ b/crates/bevy_derive/src/lib.rs @@ -27,6 +27,7 @@ use quote::format_ident; note = "The current dynamic plugin system is unsound and will be removed in 0.15." )] pub fn derive_dynamic_plugin(input: TokenStream) -> TokenStream { + #[allow(deprecated)] app_plugin::derive_dynamic_plugin(input) } From 1b97d99575e322998ec4582cfc16573f4abb4b2e Mon Sep 17 00:00:00 2001 From: BD103 <59022059+BD103@users.noreply.github.com> Date: Wed, 24 Apr 2024 08:04:46 -0400 Subject: [PATCH 4/4] chore: add deprecation notice --- crates/bevy_dynamic_plugin/src/lib.rs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/crates/bevy_dynamic_plugin/src/lib.rs b/crates/bevy_dynamic_plugin/src/lib.rs index 9d84d049f037b..7483718ebc939 100644 --- a/crates/bevy_dynamic_plugin/src/lib.rs +++ b/crates/bevy_dynamic_plugin/src/lib.rs @@ -9,12 +9,23 @@ //! This crate allows loading dynamic libraries (`.dylib`, `.so`) that export a single //! [`Plugin`](bevy_app::Plugin). For usage, see [`dynamically_load_plugin`]. //! +//! # Deprecation +//! +//! The current dynamic plugin system is unsound and will be removed in 0.15. You may be interested +//! in the [Alternatives](#alternatives) listed below. If your use-case is not supported, please +//! consider commenting on [#13080](https://github.com/bevyengine/bevy/pull/13080) describing how +//! you use dynamic plugins in your project. +//! +//! # Warning +//! //! Note that dynamic linking and loading is inherently unsafe because it allows executing foreign //! code. Additionally, Rust does not have a stable ABI and may produce //! incompatible libraries across Rust versions, or even subsequent compilations. This will not work //! well in scenarios such as modding, but can work if the dynamic plugins and the main app are //! built at the same time, such as with Downloadable Content (DLC) packs. //! +//! # Alternatives +//! //! You may be interested in these safer alternatives: //! //! - [Bevy Assets - Scripting]: Scripting and modding libraries for Bevy