mirror of
https://github.com/bevyengine/bevy
synced 2024-11-24 21:53:07 +00:00
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.
This commit is contained in:
parent
9575b20d31
commit
d722fef23d
15 changed files with 2 additions and 219 deletions
|
@ -110,9 +110,6 @@ bevy_core_pipeline = [
|
||||||
"bevy_render",
|
"bevy_render",
|
||||||
]
|
]
|
||||||
|
|
||||||
# Plugin for dynamic loading (using [libloading](https://crates.io/crates/libloading))
|
|
||||||
bevy_dynamic_plugin = ["bevy_internal/bevy_dynamic_plugin"]
|
|
||||||
|
|
||||||
# Adds gamepad support
|
# Adds gamepad support
|
||||||
bevy_gilrs = ["bevy_internal/bevy_gilrs"]
|
bevy_gilrs = ["bevy_internal/bevy_gilrs"]
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,6 @@ mod sub_app;
|
||||||
mod terminal_ctrl_c_handler;
|
mod terminal_ctrl_c_handler;
|
||||||
|
|
||||||
pub use app::*;
|
pub use app::*;
|
||||||
pub use bevy_derive::DynamicPlugin;
|
|
||||||
pub use main_schedule::*;
|
pub use main_schedule::*;
|
||||||
pub use panic_handler::*;
|
pub use panic_handler::*;
|
||||||
pub use plugin::*;
|
pub use plugin::*;
|
||||||
|
@ -38,6 +37,6 @@ pub mod prelude {
|
||||||
PostStartup, PostUpdate, PreStartup, PreUpdate, SpawnScene, Startup, Update,
|
PostStartup, PostUpdate, PreStartup, PreUpdate, SpawnScene, Startup, Update,
|
||||||
},
|
},
|
||||||
sub_app::SubApp,
|
sub_app::SubApp,
|
||||||
DynamicPlugin, Plugin, PluginGroup,
|
Plugin, PluginGroup,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -120,16 +120,6 @@ impl Plugin for PlaceholderPlugin {
|
||||||
fn build(&self, _app: &mut App) {}
|
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.
|
/// Types that represent a set of [`Plugin`]s.
|
||||||
///
|
///
|
||||||
/// This is implemented for all types which implement [`Plugin`],
|
/// This is implemented for all types which implement [`Plugin`],
|
||||||
|
|
|
@ -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)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
|
@ -9,7 +9,6 @@
|
||||||
|
|
||||||
extern crate proc_macro;
|
extern crate proc_macro;
|
||||||
|
|
||||||
mod app_plugin;
|
|
||||||
mod bevy_main;
|
mod bevy_main;
|
||||||
mod derefs;
|
mod derefs;
|
||||||
mod enum_variant_meta;
|
mod enum_variant_meta;
|
||||||
|
@ -18,19 +17,6 @@ use bevy_macro_utils::{derive_label, BevyManifest};
|
||||||
use proc_macro::TokenStream;
|
use proc_macro::TokenStream;
|
||||||
use quote::format_ident;
|
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.
|
/// Implements [`Deref`] for structs. This is especially useful when utilizing the [newtype] pattern.
|
||||||
///
|
///
|
||||||
/// For single-field structs, the implementation automatically uses that field.
|
/// For single-field structs, the implementation automatically uses that field.
|
||||||
|
|
|
@ -31,7 +31,7 @@ sysinfo = { version = "0.30.0", optional = true, default-features = false, featu
|
||||||
"apple-app-store",
|
"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]
|
[target.'cfg(any(target_os = "linux", target_os = "windows", target_os = "android"))'.dependencies]
|
||||||
sysinfo = { version = "0.30.0", optional = true, default-features = false }
|
sysinfo = { version = "0.30.0", optional = true, default-features = false }
|
||||||
|
|
||||||
|
|
|
@ -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
|
|
|
@ -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)
|
|
|
@ -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::*;
|
|
|
@ -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<P: AsRef<OsStr>>(
|
|
||||||
path: P,
|
|
||||||
) -> Result<(Library, Box<dyn Plugin>), 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<CreatePlugin> = 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<P: AsRef<OsStr>>(&mut self, path: P) -> &mut Self;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl DynamicPluginExt for App {
|
|
||||||
unsafe fn load_plugin<P: AsRef<OsStr>>(&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
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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_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_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_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_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_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" }
|
bevy_gltf = { path = "../bevy_gltf", optional = true, version = "0.15.0-dev" }
|
||||||
|
|
|
@ -29,8 +29,6 @@ pub use bevy_core_pipeline as core_pipeline;
|
||||||
#[cfg(feature = "bevy_dev_tools")]
|
#[cfg(feature = "bevy_dev_tools")]
|
||||||
pub use bevy_dev_tools as dev_tools;
|
pub use bevy_dev_tools as dev_tools;
|
||||||
pub use bevy_diagnostic as diagnostic;
|
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;
|
pub use bevy_ecs as ecs;
|
||||||
#[cfg(feature = "bevy_gilrs")]
|
#[cfg(feature = "bevy_gilrs")]
|
||||||
pub use bevy_gilrs as gilrs;
|
pub use bevy_gilrs as gilrs;
|
||||||
|
|
|
@ -51,10 +51,6 @@ pub use crate::text::prelude::*;
|
||||||
#[cfg(feature = "bevy_ui")]
|
#[cfg(feature = "bevy_ui")]
|
||||||
pub use crate::ui::prelude::*;
|
pub use crate::ui::prelude::*;
|
||||||
|
|
||||||
#[doc(hidden)]
|
|
||||||
#[cfg(feature = "bevy_dynamic_plugin")]
|
|
||||||
pub use crate::dynamic_plugin::*;
|
|
||||||
|
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
#[cfg(feature = "bevy_gizmos")]
|
#[cfg(feature = "bevy_gizmos")]
|
||||||
pub use crate::gizmos::prelude::*;
|
pub use crate::gizmos::prelude::*;
|
||||||
|
|
|
@ -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_ci_testing|Enable systems that allow for automated testing on CI|
|
||||||
|bevy_debug_stepping|Enable stepping-based debugging of Bevy systems|
|
|bevy_debug_stepping|Enable stepping-based debugging of Bevy systems|
|
||||||
|bevy_dev_tools|Provides a collection of developer tools|
|
|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|
|
|bmp|BMP image format support|
|
||||||
|dds|DDS compressed texture support|
|
|dds|DDS compressed texture support|
|
||||||
|debug_glam_assert|Enable assertions in debug builds to check the validity of parameters passed to glam|
|
|debug_glam_assert|Enable assertions in debug builds to check the validity of parameters passed to glam|
|
||||||
|
|
|
@ -16,7 +16,6 @@ crates=(
|
||||||
bevy_app
|
bevy_app
|
||||||
bevy_time
|
bevy_time
|
||||||
bevy_log
|
bevy_log
|
||||||
bevy_dynamic_plugin
|
|
||||||
bevy_asset/macros
|
bevy_asset/macros
|
||||||
bevy_asset
|
bevy_asset
|
||||||
bevy_audio
|
bevy_audio
|
||||||
|
|
Loading…
Reference in a new issue