From d722fef23de43847a1ec234a5c00aa6dbba0fd35 Mon Sep 17 00:00:00 2001 From: BD103 <59022059+BD103@users.noreply.github.com> Date: Tue, 30 Jul 2024 11:31:08 -0400 Subject: [PATCH] Remove deprecated `bevy_dynamic_plugin` (#14534) # Objective - Dynamic plugins were deprecated in #13080 due to being unsound. The plan was to deprecate them in 0.14 and remove them in 0.15. ## Solution - Remove all dynamic plugin functionality. - Update documentation to reflect this change. --- ## Migration Guide Dynamic plugins were deprecated in 0.14 for being unsound, and they have now been fully removed. Please consider using the alternatives listed in the `bevy_dynamic_plugin` crate documentation, or worst-case scenario you may copy the code from 0.14. --- Cargo.toml | 3 - crates/bevy_app/src/lib.rs | 3 +- crates/bevy_app/src/plugin.rs | 10 --- crates/bevy_derive/src/app_plugin.rs | 22 ------ crates/bevy_derive/src/lib.rs | 14 ---- crates/bevy_diagnostic/Cargo.toml | 2 +- crates/bevy_dynamic_plugin/Cargo.toml | 24 ------- crates/bevy_dynamic_plugin/README.md | 7 -- crates/bevy_dynamic_plugin/src/lib.rs | 41 ----------- crates/bevy_dynamic_plugin/src/loader.rs | 86 ------------------------ crates/bevy_internal/Cargo.toml | 1 - crates/bevy_internal/src/lib.rs | 2 - crates/bevy_internal/src/prelude.rs | 4 -- docs/cargo_features.md | 1 - tools/publish.sh | 1 - 15 files changed, 2 insertions(+), 219 deletions(-) delete mode 100644 crates/bevy_derive/src/app_plugin.rs delete mode 100644 crates/bevy_dynamic_plugin/Cargo.toml delete mode 100644 crates/bevy_dynamic_plugin/README.md delete mode 100644 crates/bevy_dynamic_plugin/src/lib.rs delete mode 100644 crates/bevy_dynamic_plugin/src/loader.rs diff --git a/Cargo.toml b/Cargo.toml index f032cdd526..dfeab0377f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -110,9 +110,6 @@ bevy_core_pipeline = [ "bevy_render", ] -# Plugin for dynamic loading (using [libloading](https://crates.io/crates/libloading)) -bevy_dynamic_plugin = ["bevy_internal/bevy_dynamic_plugin"] - # Adds gamepad support bevy_gilrs = ["bevy_internal/bevy_gilrs"] diff --git a/crates/bevy_app/src/lib.rs b/crates/bevy_app/src/lib.rs index 86bec47521..d22669a634 100644 --- a/crates/bevy_app/src/lib.rs +++ b/crates/bevy_app/src/lib.rs @@ -18,7 +18,6 @@ mod sub_app; mod terminal_ctrl_c_handler; pub use app::*; -pub use bevy_derive::DynamicPlugin; pub use main_schedule::*; pub use panic_handler::*; pub use plugin::*; @@ -38,6 +37,6 @@ pub mod prelude { PostStartup, PostUpdate, PreStartup, PreUpdate, SpawnScene, Startup, Update, }, sub_app::SubApp, - DynamicPlugin, Plugin, PluginGroup, + Plugin, PluginGroup, }; } diff --git a/crates/bevy_app/src/plugin.rs b/crates/bevy_app/src/plugin.rs index fdaa579b2b..006b645cbe 100644 --- a/crates/bevy_app/src/plugin.rs +++ b/crates/bevy_app/src/plugin.rs @@ -120,16 +120,6 @@ impl Plugin for PlaceholderPlugin { fn build(&self, _app: &mut App) {} } -/// A type representing an unsafe function that returns a mutable pointer to a [`Plugin`]. -/// 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. /// /// This is implemented for all types which implement [`Plugin`], diff --git a/crates/bevy_derive/src/app_plugin.rs b/crates/bevy_derive/src/app_plugin.rs deleted file mode 100644 index 108f567ac4..0000000000 --- a/crates/bevy_derive/src/app_plugin.rs +++ /dev/null @@ -1,22 +0,0 @@ -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; - - TokenStream::from(quote! { - #[no_mangle] - pub extern "C" fn _bevy_create_plugin() -> *mut dyn bevy::app::Plugin { - // make sure the constructor is the correct type. - let object = #struct_name {}; - let boxed = Box::new(object); - Box::into_raw(boxed) - } - }) -} diff --git a/crates/bevy_derive/src/lib.rs b/crates/bevy_derive/src/lib.rs index 19fb1b71c7..2151f4d09f 100644 --- a/crates/bevy_derive/src/lib.rs +++ b/crates/bevy_derive/src/lib.rs @@ -9,7 +9,6 @@ extern crate proc_macro; -mod app_plugin; mod bevy_main; mod derefs; mod enum_variant_meta; @@ -18,19 +17,6 @@ use bevy_macro_utils::{derive_label, BevyManifest}; 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 { - #[allow(deprecated)] - app_plugin::derive_dynamic_plugin(input) -} - /// Implements [`Deref`] for structs. This is especially useful when utilizing the [newtype] pattern. /// /// For single-field structs, the implementation automatically uses that field. diff --git a/crates/bevy_diagnostic/Cargo.toml b/crates/bevy_diagnostic/Cargo.toml index 6fa9cd5706..1b320a5649 100644 --- a/crates/bevy_diagnostic/Cargo.toml +++ b/crates/bevy_diagnostic/Cargo.toml @@ -31,7 +31,7 @@ sysinfo = { version = "0.30.0", optional = true, default-features = false, featu "apple-app-store", ] } -# Only include when not bevy_dynamic_plugin and on linux/windows/android +# Only include when on linux/windows/android [target.'cfg(any(target_os = "linux", target_os = "windows", target_os = "android"))'.dependencies] sysinfo = { version = "0.30.0", optional = true, default-features = false } diff --git a/crates/bevy_dynamic_plugin/Cargo.toml b/crates/bevy_dynamic_plugin/Cargo.toml deleted file mode 100644 index 47d3ef57ae..0000000000 --- a/crates/bevy_dynamic_plugin/Cargo.toml +++ /dev/null @@ -1,24 +0,0 @@ -[package] -name = "bevy_dynamic_plugin" -version = "0.15.0-dev" -edition = "2021" -description = "Provides dynamic plugin loading capabilities for non-wasm platforms" -homepage = "https://bevyengine.org" -repository = "https://github.com/bevyengine/bevy" -license = "MIT OR Apache-2.0" -keywords = ["bevy"] - -[dependencies] -# bevy -bevy_app = { path = "../bevy_app", version = "0.15.0-dev" } - -# other -libloading = { version = "0.8" } -thiserror = "1.0" - -[lints] -workspace = true - -[package.metadata.docs.rs] -rustdoc-args = ["-Zunstable-options", "--generate-link-to-definition"] -all-features = true diff --git a/crates/bevy_dynamic_plugin/README.md b/crates/bevy_dynamic_plugin/README.md deleted file mode 100644 index 77b1b39af1..0000000000 --- a/crates/bevy_dynamic_plugin/README.md +++ /dev/null @@ -1,7 +0,0 @@ -# Bevy Dynamic Plugin - -[![License](https://img.shields.io/badge/license-MIT%2FApache-blue.svg)](https://github.com/bevyengine/bevy#license) -[![Crates.io](https://img.shields.io/crates/v/bevy_dynamic_plugin.svg)](https://crates.io/crates/bevy_dynamic_plugin) -[![Downloads](https://img.shields.io/crates/d/bevy_dynamic_plugin.svg)](https://crates.io/crates/bevy_dynamic_plugin) -[![Docs](https://docs.rs/bevy_dynamic_plugin/badge.svg)](https://docs.rs/bevy_dynamic_plugin/latest/bevy_dynamic_plugin/) -[![Discord](https://img.shields.io/discord/691052431525675048.svg?label=&logo=discord&logoColor=ffffff&color=7389D8&labelColor=6A7EC2)](https://discord.gg/bevy) diff --git a/crates/bevy_dynamic_plugin/src/lib.rs b/crates/bevy_dynamic_plugin/src/lib.rs deleted file mode 100644 index 7483718ebc..0000000000 --- a/crates/bevy_dynamic_plugin/src/lib.rs +++ /dev/null @@ -1,41 +0,0 @@ -#![cfg_attr(docsrs, feature(doc_auto_cfg))] -#![doc( - html_logo_url = "https://bevyengine.org/assets/icon.png", - html_favicon_url = "https://bevyengine.org/assets/icon.png" -)] - -//! Bevy's dynamic plugin loading functionality. -//! -//! 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 -//! - [Bevy Assets - Development tools]: Hot reloading and other development functionality -//! - [`stabby`]: Stable Rust ABI -//! -//! [Bevy Assets - Scripting]: https://bevyengine.org/assets/#scripting -//! [Bevy Assets - Development tools]: https://bevyengine.org/assets/#development-tools -//! [`stabby`]: https://github.com/ZettaScaleLabs/stabby - -mod loader; - -pub use loader::*; diff --git a/crates/bevy_dynamic_plugin/src/loader.rs b/crates/bevy_dynamic_plugin/src/loader.rs deleted file mode 100644 index 09c65d6273..0000000000 --- a/crates/bevy_dynamic_plugin/src/loader.rs +++ /dev/null @@ -1,86 +0,0 @@ -#![allow(unsafe_code)] -#![allow(deprecated)] - -use libloading::{Library, Symbol}; -use std::ffi::OsStr; -use thiserror::Error; - -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}")] - Library(#[source] libloading::Error), - /// An error occurred when loading a library without a valid Bevy plugin. - #[error("dynamic library does not contain a valid Bevy dynamic plugin")] - Plugin(#[source] libloading::Error), -} - -/// Dynamically links a plugin at the given path. The plugin must export a function with the -/// [`CreatePlugin`] signature named `_bevy_create_plugin`. -/// -/// # Safety -/// -/// The specified plugin must be linked against the exact same `libbevy.so` as this program. -/// In addition the `_bevy_create_plugin` symbol must not be manually created, but instead created -/// by deriving `DynamicPlugin` on a unit struct implementing [`Plugin`]. -/// -/// Dynamically loading plugins is orchestrated through dynamic linking. When linking against -/// 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> { - // SAFETY: Caller must follow the safety requirements of Library::new. - let lib = unsafe { Library::new(path).map_err(DynamicPluginLoadError::Library)? }; - - // SAFETY: Loaded plugins are not allowed to specify `_bevy_create_plugin` symbol manually, but - // must instead automatically generate it through `DynamicPlugin`. - let func: Symbol = unsafe { - lib.get(b"_bevy_create_plugin") - .map_err(DynamicPluginLoadError::Plugin)? - }; - - // SAFETY: `func` is automatically generated and is guaranteed to return a pointer created using - // `Box::into_raw`. - let plugin = unsafe { Box::from_raw(func()) }; - - Ok((lib, 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. - /// - /// For more details, see [`dynamically_load_plugin`]. - /// - /// # Safety - /// - /// See [`dynamically_load_plugin`]'s safety section. - unsafe fn load_plugin>(&mut self, path: P) -> &mut Self; -} - -impl DynamicPluginExt for App { - unsafe fn load_plugin>(&mut self, path: P) -> &mut Self { - // SAFETY: Follows the same safety requirements as `dynamically_load_plugin`. - let (lib, plugin) = unsafe { dynamically_load_plugin(path).unwrap() }; - std::mem::forget(lib); // Ensure that the library is not automatically unloaded - plugin.build(self); - self - } -} diff --git a/crates/bevy_internal/Cargo.toml b/crates/bevy_internal/Cargo.toml index 956eb752cb..d3fdcc104d 100644 --- a/crates/bevy_internal/Cargo.toml +++ b/crates/bevy_internal/Cargo.toml @@ -230,7 +230,6 @@ bevy_audio = { path = "../bevy_audio", optional = true, version = "0.15.0-dev" } bevy_color = { path = "../bevy_color", optional = true, version = "0.15.0-dev" } bevy_core_pipeline = { path = "../bevy_core_pipeline", optional = true, version = "0.15.0-dev" } bevy_dev_tools = { path = "../bevy_dev_tools", optional = true, version = "0.15.0-dev" } -bevy_dynamic_plugin = { path = "../bevy_dynamic_plugin", optional = true, version = "0.15.0-dev" } bevy_gilrs = { path = "../bevy_gilrs", optional = true, version = "0.15.0-dev" } bevy_gizmos = { path = "../bevy_gizmos", optional = true, version = "0.15.0-dev", default-features = false } bevy_gltf = { path = "../bevy_gltf", optional = true, version = "0.15.0-dev" } diff --git a/crates/bevy_internal/src/lib.rs b/crates/bevy_internal/src/lib.rs index 1f03cf09dc..bc71e57efa 100644 --- a/crates/bevy_internal/src/lib.rs +++ b/crates/bevy_internal/src/lib.rs @@ -29,8 +29,6 @@ pub use bevy_core_pipeline as core_pipeline; #[cfg(feature = "bevy_dev_tools")] pub use bevy_dev_tools as dev_tools; pub use bevy_diagnostic as diagnostic; -#[cfg(feature = "bevy_dynamic_plugin")] -pub use bevy_dynamic_plugin as dynamic_plugin; pub use bevy_ecs as ecs; #[cfg(feature = "bevy_gilrs")] pub use bevy_gilrs as gilrs; diff --git a/crates/bevy_internal/src/prelude.rs b/crates/bevy_internal/src/prelude.rs index 70881a3d39..7201e170d3 100644 --- a/crates/bevy_internal/src/prelude.rs +++ b/crates/bevy_internal/src/prelude.rs @@ -51,10 +51,6 @@ pub use crate::text::prelude::*; #[cfg(feature = "bevy_ui")] pub use crate::ui::prelude::*; -#[doc(hidden)] -#[cfg(feature = "bevy_dynamic_plugin")] -pub use crate::dynamic_plugin::*; - #[doc(hidden)] #[cfg(feature = "bevy_gizmos")] pub use crate::gizmos::prelude::*; diff --git a/docs/cargo_features.md b/docs/cargo_features.md index 1c538a821b..d2cbf06a23 100644 --- a/docs/cargo_features.md +++ b/docs/cargo_features.md @@ -54,7 +54,6 @@ The default feature set enables most of the expected features of a game engine, |bevy_ci_testing|Enable systems that allow for automated testing on CI| |bevy_debug_stepping|Enable stepping-based debugging of Bevy systems| |bevy_dev_tools|Provides a collection of developer tools| -|bevy_dynamic_plugin|Plugin for dynamic loading (using [libloading](https://crates.io/crates/libloading))| |bmp|BMP image format support| |dds|DDS compressed texture support| |debug_glam_assert|Enable assertions in debug builds to check the validity of parameters passed to glam| diff --git a/tools/publish.sh b/tools/publish.sh index be02f60704..72ddab7f10 100644 --- a/tools/publish.sh +++ b/tools/publish.sh @@ -16,7 +16,6 @@ crates=( bevy_app bevy_time bevy_log - bevy_dynamic_plugin bevy_asset/macros bevy_asset bevy_audio