Skip to content

Commit

Permalink
Add bevy_dylib to force dynamic linking of bevy (#808)
Browse files Browse the repository at this point in the history
This easily improve compilation time by 2x
  • Loading branch information
bjorn3 committed Nov 10, 2020
1 parent b113809 commit 80a0448
Show file tree
Hide file tree
Showing 17 changed files with 349 additions and 249 deletions.
122 changes: 54 additions & 68 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,102 +3,88 @@ name = "bevy"
version = "0.3.0"
edition = "2018"
authors = [
"Bevy Contributors <bevyengine@gmail.com>",
"Carter Anderson <mcanders1@gmail.com>",
"Bevy Contributors <bevyengine@gmail.com>",
"Carter Anderson <mcanders1@gmail.com>",
]
categories = ["game-engines", "graphics", "gui", "rendering"]
description = "A refreshingly simple data-driven game engine and app framework"
exclude = ["assets/**/*", "tools/**/*", ".github/**/*", "crates/**/*"]
homepage = "https://bevyengine.org"
repository = "https://github.com/bevyengine/bevy"
license = "MIT"
keywords = ["game", "engine", "gamedev", "graphics", "bevy"]
categories = ["game-engines", "graphics", "gui", "rendering"]
readme = "README.md"
exclude = ["assets/**/*", "tools/**/*", ".github/**/*", "crates/**/*"]
license = "MIT"
repository = "https://github.com/bevyengine/bevy"

[workspace]
exclude = ["benches"]
members = ["crates/*", "crates/bevy_ecs/hecs", "examples/ios"]

[features]
default = [
"bevy_audio",
"bevy_dynamic_plugin",
"bevy_gilrs",
"bevy_gltf",
"bevy_wgpu",
"bevy_winit",
"render",
"png",
"hdr",
"mp3",
"x11",
"bevy_audio",
"bevy_dynamic_plugin",
"bevy_gilrs",
"bevy_gltf",
"bevy_wgpu",
"bevy_winit",
"render",
"png",
"hdr",
"mp3",
"x11",
]

profiler = ["bevy_ecs/profiler", "bevy_diagnostic/profiler"]
wgpu_trace = ["bevy_wgpu/trace"]
# Force dynamic linking, which improves iterative compile times
dynamic = ["bevy_dylib"]

# Rendering support
render = ["bevy_pbr", "bevy_render", "bevy_sprite", "bevy_text", "bevy_ui"]
render = ["bevy_internal/bevy_pbr", "bevy_internal/bevy_render", "bevy_internal/bevy_sprite", "bevy_internal/bevy_text", "bevy_internal/bevy_ui"]

# Optional bevy crates
bevy_audio = ["bevy_internal/bevy_audio"]
bevy_dynamic_plugin = ["bevy_internal/bevy_dynamic_plugin"]
bevy_gilrs = ["bevy_internal/bevy_gilrs"]
bevy_gltf = ["bevy_internal/bevy_gltf"]
bevy_wgpu = ["bevy_internal/bevy_wgpu"]
bevy_winit = ["bevy_internal/bevy_winit"]

profiler = ["bevy_internal/profiler"]
wgpu_trace = ["bevy_internal/wgpu_trace"]

# Image format support for texture loading (PNG and HDR are enabled by default)
png = ["bevy_render/png"]
hdr = ["bevy_render/hdr"]
hdr = ["bevy_internal/hdr"]
png = ["bevy_internal/png"]

# Audio format support (MP3 is enabled by default)
mp3 = ["bevy_audio/mp3"]
flac = ["bevy_audio/flac"]
wav = ["bevy_audio/wav"]
vorbis = ["bevy_audio/vorbis"]
flac = ["bevy_internal/flac"]
mp3 = ["bevy_internal/mp3"]
vorbis = ["bevy_internal/vorbis"]
wav = ["bevy_internal/wav"]

serialize = ["bevy_input/serialize"]
serialize = ["bevy_internal/serialize"]

# Display server protocol support (X11 is enabled by default)
wayland = ["bevy_winit/wayland"]
x11 = ["bevy_winit/x11"]

[workspace]
members = ["crates/*", "crates/bevy_ecs/hecs", "examples/ios"]
exclude = ["benches"]
wayland = ["bevy_internal/wayland"]
x11 = ["bevy_internal/x11"]

[dependencies]
# bevy
bevy_app = { path = "crates/bevy_app", version = "0.3.0" }
bevy_asset = { path = "crates/bevy_asset", version = "0.3.0" }
bevy_type_registry = { path = "crates/bevy_type_registry", version = "0.3.0" }
bevy_core = { path = "crates/bevy_core", version = "0.3.0" }
bevy_diagnostic = { path = "crates/bevy_diagnostic", version = "0.3.0" }
bevy_ecs = { path = "crates/bevy_ecs", version = "0.3.0" }
bevy_input = { path = "crates/bevy_input", version = "0.3.0" }
bevy_math = { path = "crates/bevy_math", version = "0.3.0" }
bevy_property = { path = "crates/bevy_property", version = "0.3.0" }
bevy_scene = { path = "crates/bevy_scene", version = "0.3.0" }
bevy_transform = { path = "crates/bevy_transform", version = "0.3.0" }
bevy_utils = { path = "crates/bevy_utils", version = "0.3.0" }
bevy_window = { path = "crates/bevy_window", version = "0.3.0" }
bevy_tasks = { path = "crates/bevy_tasks", version = "0.3.0" }
# bevy (optional)
bevy_audio = { path = "crates/bevy_audio", optional = true, version = "0.3.0" }
bevy_gltf = { path = "crates/bevy_gltf", optional = true, version = "0.3.0" }
bevy_pbr = { path = "crates/bevy_pbr", optional = true, version = "0.3.0" }
bevy_render = { path = "crates/bevy_render", optional = true, version = "0.3.0" }
bevy_dynamic_plugin = { path = "crates/bevy_dynamic_plugin", optional = true, version = "0.3.0" }
bevy_sprite = { path = "crates/bevy_sprite", optional = true, version = "0.3.0" }
bevy_text = { path = "crates/bevy_text", optional = true, version = "0.3.0" }
bevy_ui = { path = "crates/bevy_ui", optional = true, version = "0.3.0" }
bevy_wgpu = { path = "crates/bevy_wgpu", optional = true, version = "0.3.0" }
bevy_winit = { path = "crates/bevy_winit", optional = true, version = "0.3.0" }
bevy_gilrs = { path = "crates/bevy_gilrs", optional = true, version = "0.3.0" }
bevy_dylib = {path = "crates/bevy_dylib", version = "0.3.0", default-features = false, optional = true}
bevy_internal = {path = "crates/bevy_internal", version = "0.3.0", default-features = false}

[dev-dependencies]
rand = "0.7.3"
serde = { version = "1", features = ["derive"] }
anyhow = "1.0"
log = "0.4"
rand = "0.7.3"
ron = "0.6"
anyhow = "1.0"
serde = {version = "1", features = ["derive"]}

# bevy (Android)
[target.'cfg(target_os = "android")'.dependencies]
ndk-glue = { version = "0.2", features = ["logger"] }
android_logger = "0.9"
ndk-glue = {version = "0.2", features = ["logger"]}

[target.'cfg(target_arch = "wasm32")'.dev-dependencies]
console_error_panic_hook = "0.1.6"
console_log = { version = "0.2", features = ["color"] }
console_log = {version = "0.2", features = ["color"]}

[[example]]
name = "hello_world"
Expand Down Expand Up @@ -333,11 +319,11 @@ path = "examples/wasm/assets_wasm.rs"
required-features = ["bevy_winit"]

[[example]]
crate-type = ["cdylib"]
name = "android"
path = "examples/android/android.rs"
crate-type = ["cdylib"]

[package.metadata.android]
build_targets = ["aarch64-linux-android", "armv7-linux-androideabi"]
target_sdk_version = 29
min_sdk_version = 16
target_sdk_version = 29
2 changes: 1 addition & 1 deletion crates/bevy_derive/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ proc-macro = true

[dependencies]
Inflector = { version = "0.11.4", default-features = false }
proc-macro-crate = "0.1.5"
find-crate = "0.5"
proc-macro2 = "1.0"
quote = "1.0"
syn = "1.0"
Expand Down
32 changes: 17 additions & 15 deletions crates/bevy_derive/src/modules.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use find_crate::Manifest;
use proc_macro::TokenStream;
use proc_macro_crate::crate_name;
use syn::{Attribute, Path};

#[derive(Debug)]
Expand All @@ -12,13 +12,13 @@ pub struct Modules {
}

impl Modules {
pub fn meta() -> Modules {
pub fn meta(name: &str) -> Modules {
Modules {
bevy_asset: "bevy::asset".to_string(),
bevy_render: "bevy::render".to_string(),
bevy_core: "bevy::core".to_string(),
bevy_app: "bevy::app".to_string(),
bevy_type_registry: "bevy::type_registry".to_string(),
bevy_asset: format!("{}::asset", name),
bevy_render: format!("{}::render", name),
bevy_core: format!("{}::core", name),
bevy_app: format!("{}::app", name),
bevy_type_registry: format!("{}::type_registry", name),
}
}

Expand All @@ -33,19 +33,21 @@ impl Modules {
}
}

fn use_meta() -> bool {
crate_name("bevy").is_ok()
fn get_meta() -> Option<Modules> {
let manifest = Manifest::new().unwrap();
if let Some(package) = manifest.find(|name| name == "bevy") {
Some(Modules::meta(&package.name))
} else if let Some(package) = manifest.find(|name| name == "bevy_internal") {
Some(Modules::meta(&package.name))
} else {
None
}
}

const AS_CRATE_ATTRIBUTE_NAME: &str = "as_crate";

pub fn get_modules(attributes: &[Attribute]) -> Modules {
let mut modules = if use_meta() {
Modules::meta()
} else {
Modules::external()
};

let mut modules = get_meta().unwrap_or_else(Modules::external);
for attribute in attributes.iter() {
if *attribute.path.get_ident().as_ref().unwrap() == AS_CRATE_ATTRIBUTE_NAME {
let value = attribute.tokens.to_string();
Expand Down
19 changes: 19 additions & 0 deletions crates/bevy_dylib/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
[package]
name = "bevy_dylib"
version = "0.3.0"
edition = "2018"
authors = [
"Bevy Contributors <bevyengine@gmail.com>",
"Carter Anderson <mcanders1@gmail.com>",
]
description = "Force the Bevy Engine to be dynamically linked for faster linking"
homepage = "https://bevyengine.org"
repository = "https://github.com/bevyengine/bevy"
license = "MIT"
keywords = ["bevy"]

[lib]
crate-type = ["dylib"]

[dependencies]
bevy_internal = { path = "../bevy_internal", version = "0.3.0", default-features = false }
12 changes: 12 additions & 0 deletions crates/bevy_dylib/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
//! Forces dynamic linking of Bevy.
//!
//! Dynamically linking Bevy makes the "link" step much faster. This can be achieved by adding
//! `bevy_dylib` as dependency and `#[allow(unused_imports)] use bevy_dylib` to `main.rs`. It is
//! recommended to disable the `bevy_dylib` dependency in release mode by adding
//! `#[cfg(debug_assertions)]` to the `use` statement. Otherwise you will have to ship `libstd.so`
//! and `libbevy_dylib.so` with your game.

// Force linking of the main bevy crate
#[allow(unused_imports)]
#[allow(clippy::single_component_path_imports)]
use bevy_internal;
2 changes: 1 addition & 1 deletion crates/bevy_ecs/hecs/macros/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,4 @@ proc-macro = true
syn = "1.0"
quote = "1.0"
proc-macro2 = "1.0"
proc-macro-crate = "0.1.5"
find-crate = "0.5"
20 changes: 11 additions & 9 deletions crates/bevy_ecs/hecs/macros/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@ extern crate proc_macro;

use std::borrow::Cow;

use find_crate::Manifest;
use proc_macro::TokenStream;
use proc_macro2::{Span, TokenStream as TokenStream2};
use proc_macro_crate::crate_name;
use quote::quote;
use syn::{
parse::ParseStream, parse_macro_input, Data, DataStruct, DeriveInput, Error, Field, Fields,
Expand Down Expand Up @@ -54,12 +54,13 @@ fn derive_bundle_(input: DeriveInput) -> Result<TokenStream2> {
}
};
let (tys, field_members) = struct_fields(&data.fields);
let path_str = if crate_name("bevy").is_ok() {
"bevy::ecs"
} else if crate_name("bevy_ecs").is_ok() {
"bevy_ecs"
let manifest = Manifest::new().unwrap();
let path_str = if let Some(package) = manifest.find(|name| name == "bevy") {
format!("{}::ecs", package.name)
} else if let Some(package) = manifest.find(|name| name == "bevy_ecs") {
package.name
} else {
"bevy_hecs"
"bevy_hecs".to_string()
};
let crate_path: Path = syn::parse(path_str.parse::<TokenStream>().unwrap()).unwrap();
let field_idents = member_as_idents(&field_members);
Expand Down Expand Up @@ -354,10 +355,11 @@ pub fn derive_system_param(input: TokenStream) -> TokenStream {
_ => panic!("expected a struct with named fields"),
};

let path_str = if crate_name("bevy").is_ok() {
"bevy::ecs"
let manifest = Manifest::new().unwrap();
let path_str = if let Some(package) = manifest.find(|name| name == "bevy") {
format!("{}::ecs", package.name)
} else {
"bevy_ecs"
"bevy_ecs".to_string()
};
let path: Path = syn::parse(path_str.parse::<TokenStream>().unwrap()).unwrap();

Expand Down
64 changes: 64 additions & 0 deletions crates/bevy_internal/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
[package]
name = "bevy_internal"
version = "0.3.0"
edition = "2018"
authors = [
"Bevy Contributors <bevyengine@gmail.com>",
"Carter Anderson <mcanders1@gmail.com>",
]
description = "An internal Bevy crate used to facilitate optional dynamic linking via the 'dynamic' feature"
homepage = "https://bevyengine.org"
repository = "https://github.com/bevyengine/bevy"
license = "MIT"
keywords = ["game", "engine", "gamedev", "graphics", "bevy"]
categories = ["game-engines", "graphics", "gui", "rendering"]

[features]
profiler = ["bevy_ecs/profiler", "bevy_diagnostic/profiler"]
wgpu_trace = ["bevy_wgpu/trace"]

# Image format support for texture loading (PNG and HDR are enabled by default)
hdr = ["bevy_render/hdr"]
png = ["bevy_render/png"]

# Audio format support (MP3 is enabled by default)
flac = ["bevy_audio/flac"]
mp3 = ["bevy_audio/mp3"]
vorbis = ["bevy_audio/vorbis"]
wav = ["bevy_audio/wav"]

serialize = ["bevy_input/serialize"]

# Display server protocol support (X11 is enabled by default)
wayland = ["bevy_winit/wayland"]
x11 = ["bevy_winit/x11"]

[dependencies]
# bevy
bevy_app = { path = "../bevy_app", version = "0.3.0" }
bevy_asset = { path = "../bevy_asset", version = "0.3.0" }
bevy_type_registry = { path = "../bevy_type_registry", version = "0.3.0" }
bevy_core = { path = "../bevy_core", version = "0.3.0" }
bevy_diagnostic = { path = "../bevy_diagnostic", version = "0.3.0" }
bevy_ecs = { path = "../bevy_ecs", version = "0.3.0" }
bevy_input = { path = "../bevy_input", version = "0.3.0" }
bevy_math = { path = "../bevy_math", version = "0.3.0" }
bevy_property = { path = "../bevy_property", version = "0.3.0" }
bevy_scene = { path = "../bevy_scene", version = "0.3.0" }
bevy_transform = { path = "../bevy_transform", version = "0.3.0" }
bevy_utils = { path = "../bevy_utils", version = "0.3.0" }
bevy_window = { path = "../bevy_window", version = "0.3.0" }
bevy_tasks = { path = "../bevy_tasks", version = "0.3.0" }
# bevy (optional)
bevy_audio = { path = "../bevy_audio", optional = true, version = "0.3.0" }
bevy_gltf = { path = "../bevy_gltf", optional = true, version = "0.3.0" }
bevy_pbr = { path = "../bevy_pbr", optional = true, version = "0.3.0" }
bevy_render = { path = "../bevy_render", optional = true, version = "0.3.0" }
bevy_dynamic_plugin = { path = "../bevy_dynamic_plugin", optional = true, version = "0.3.0" }
bevy_sprite = { path = "../bevy_sprite", optional = true, version = "0.3.0" }
bevy_text = { path = "../bevy_text", optional = true, version = "0.3.0" }
bevy_ui = { path = "../bevy_ui", optional = true, version = "0.3.0" }
bevy_wgpu = { path = "../bevy_wgpu", optional = true, version = "0.3.0" }
bevy_winit = { path = "../bevy_winit", optional = true, version = "0.3.0" }
bevy_gilrs = { path = "../bevy_gilrs", optional = true, version = "0.3.0" }

File renamed without changes.
Loading

0 comments on commit 80a0448

Please sign in to comment.