Skip to content

Commit ecfd251

Browse files
bjorn3cart
authored andcommitted
Add bevy_dylib to force dynamic linking of bevy
This easily improve compilation time by 2x
1 parent b113809 commit ecfd251

File tree

17 files changed

+390
-290
lines changed

17 files changed

+390
-290
lines changed

Cargo.toml

+54-68
Original file line numberDiff line numberDiff line change
@@ -3,102 +3,88 @@ name = "bevy"
33
version = "0.3.0"
44
edition = "2018"
55
authors = [
6-
"Bevy Contributors <bevyengine@gmail.com>",
7-
"Carter Anderson <mcanders1@gmail.com>",
6+
"Bevy Contributors <bevyengine@gmail.com>",
7+
"Carter Anderson <mcanders1@gmail.com>",
88
]
9+
categories = ["game-engines", "graphics", "gui", "rendering"]
910
description = "A refreshingly simple data-driven game engine and app framework"
11+
exclude = ["assets/**/*", "tools/**/*", ".github/**/*", "crates/**/*"]
1012
homepage = "https://bevyengine.org"
11-
repository = "https://github.com/bevyengine/bevy"
12-
license = "MIT"
1313
keywords = ["game", "engine", "gamedev", "graphics", "bevy"]
14-
categories = ["game-engines", "graphics", "gui", "rendering"]
15-
readme = "README.md"
16-
exclude = ["assets/**/*", "tools/**/*", ".github/**/*", "crates/**/*"]
14+
license = "MIT"
15+
repository = "https://github.com/bevyengine/bevy"
16+
17+
[workspace]
18+
exclude = ["benches"]
19+
members = ["crates/*", "crates/bevy_ecs/hecs", "examples/ios"]
1720

1821
[features]
1922
default = [
20-
"bevy_audio",
21-
"bevy_dynamic_plugin",
22-
"bevy_gilrs",
23-
"bevy_gltf",
24-
"bevy_wgpu",
25-
"bevy_winit",
26-
"render",
27-
"png",
28-
"hdr",
29-
"mp3",
30-
"x11",
23+
"bevy_audio",
24+
"bevy_dynamic_plugin",
25+
"bevy_gilrs",
26+
"bevy_gltf",
27+
"bevy_wgpu",
28+
"bevy_winit",
29+
"render",
30+
"png",
31+
"hdr",
32+
"mp3",
33+
"x11",
3134
]
3235

33-
profiler = ["bevy_ecs/profiler", "bevy_diagnostic/profiler"]
34-
wgpu_trace = ["bevy_wgpu/trace"]
36+
# Force dynamic linking, which improves iterative compile times
37+
dynamic = ["bevy_dylib"]
3538

3639
# Rendering support
37-
render = ["bevy_pbr", "bevy_render", "bevy_sprite", "bevy_text", "bevy_ui"]
40+
render = ["bevy_internal/bevy_pbr", "bevy_internal/bevy_render", "bevy_internal/bevy_sprite", "bevy_internal/bevy_text", "bevy_internal/bevy_ui"]
41+
42+
# Optional bevy crates
43+
bevy_audio = ["bevy_internal/bevy_audio"]
44+
bevy_dynamic_plugin = ["bevy_internal/bevy_dynamic_plugin"]
45+
bevy_gilrs = ["bevy_internal/bevy_gilrs"]
46+
bevy_gltf = ["bevy_internal/bevy_gltf"]
47+
bevy_wgpu = ["bevy_internal/bevy_wgpu"]
48+
bevy_winit = ["bevy_internal/bevy_winit"]
49+
50+
profiler = ["bevy_internal/profiler"]
51+
wgpu_trace = ["bevy_internal/wgpu_trace"]
52+
3853
# Image format support for texture loading (PNG and HDR are enabled by default)
39-
png = ["bevy_render/png"]
40-
hdr = ["bevy_render/hdr"]
54+
hdr = ["bevy_internal/hdr"]
55+
png = ["bevy_internal/png"]
4156

4257
# Audio format support (MP3 is enabled by default)
43-
mp3 = ["bevy_audio/mp3"]
44-
flac = ["bevy_audio/flac"]
45-
wav = ["bevy_audio/wav"]
46-
vorbis = ["bevy_audio/vorbis"]
58+
flac = ["bevy_internal/flac"]
59+
mp3 = ["bevy_internal/mp3"]
60+
vorbis = ["bevy_internal/vorbis"]
61+
wav = ["bevy_internal/wav"]
4762

48-
serialize = ["bevy_input/serialize"]
63+
serialize = ["bevy_internal/serialize"]
4964

5065
# Display server protocol support (X11 is enabled by default)
51-
wayland = ["bevy_winit/wayland"]
52-
x11 = ["bevy_winit/x11"]
53-
54-
[workspace]
55-
members = ["crates/*", "crates/bevy_ecs/hecs", "examples/ios"]
56-
exclude = ["benches"]
66+
wayland = ["bevy_internal/wayland"]
67+
x11 = ["bevy_internal/x11"]
5768

5869
[dependencies]
59-
# bevy
60-
bevy_app = { path = "crates/bevy_app", version = "0.3.0" }
61-
bevy_asset = { path = "crates/bevy_asset", version = "0.3.0" }
62-
bevy_type_registry = { path = "crates/bevy_type_registry", version = "0.3.0" }
63-
bevy_core = { path = "crates/bevy_core", version = "0.3.0" }
64-
bevy_diagnostic = { path = "crates/bevy_diagnostic", version = "0.3.0" }
65-
bevy_ecs = { path = "crates/bevy_ecs", version = "0.3.0" }
66-
bevy_input = { path = "crates/bevy_input", version = "0.3.0" }
67-
bevy_math = { path = "crates/bevy_math", version = "0.3.0" }
68-
bevy_property = { path = "crates/bevy_property", version = "0.3.0" }
69-
bevy_scene = { path = "crates/bevy_scene", version = "0.3.0" }
70-
bevy_transform = { path = "crates/bevy_transform", version = "0.3.0" }
71-
bevy_utils = { path = "crates/bevy_utils", version = "0.3.0" }
72-
bevy_window = { path = "crates/bevy_window", version = "0.3.0" }
73-
bevy_tasks = { path = "crates/bevy_tasks", version = "0.3.0" }
74-
# bevy (optional)
75-
bevy_audio = { path = "crates/bevy_audio", optional = true, version = "0.3.0" }
76-
bevy_gltf = { path = "crates/bevy_gltf", optional = true, version = "0.3.0" }
77-
bevy_pbr = { path = "crates/bevy_pbr", optional = true, version = "0.3.0" }
78-
bevy_render = { path = "crates/bevy_render", optional = true, version = "0.3.0" }
79-
bevy_dynamic_plugin = { path = "crates/bevy_dynamic_plugin", optional = true, version = "0.3.0" }
80-
bevy_sprite = { path = "crates/bevy_sprite", optional = true, version = "0.3.0" }
81-
bevy_text = { path = "crates/bevy_text", optional = true, version = "0.3.0" }
82-
bevy_ui = { path = "crates/bevy_ui", optional = true, version = "0.3.0" }
83-
bevy_wgpu = { path = "crates/bevy_wgpu", optional = true, version = "0.3.0" }
84-
bevy_winit = { path = "crates/bevy_winit", optional = true, version = "0.3.0" }
85-
bevy_gilrs = { path = "crates/bevy_gilrs", optional = true, version = "0.3.0" }
70+
bevy_dylib = {path = "crates/bevy_dylib", version = "0.3.0", default-features = false, optional = true}
71+
bevy_internal = {path = "crates/bevy_internal", version = "0.3.0", default-features = false}
8672

8773
[dev-dependencies]
88-
rand = "0.7.3"
89-
serde = { version = "1", features = ["derive"] }
74+
anyhow = "1.0"
9075
log = "0.4"
76+
rand = "0.7.3"
9177
ron = "0.6"
92-
anyhow = "1.0"
78+
serde = {version = "1", features = ["derive"]}
9379

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

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

10389
[[example]]
10490
name = "hello_world"
@@ -333,11 +319,11 @@ path = "examples/wasm/assets_wasm.rs"
333319
required-features = ["bevy_winit"]
334320

335321
[[example]]
322+
crate-type = ["cdylib"]
336323
name = "android"
337324
path = "examples/android/android.rs"
338-
crate-type = ["cdylib"]
339325

340326
[package.metadata.android]
341327
build_targets = ["aarch64-linux-android", "armv7-linux-androideabi"]
342-
target_sdk_version = 29
343328
min_sdk_version = 16
329+
target_sdk_version = 29

crates/bevy_derive/Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ proc-macro = true
1717

1818
[dependencies]
1919
Inflector = { version = "0.11.4", default-features = false }
20-
proc-macro-crate = "0.1.5"
20+
find-crate = "0.5"
2121
proc-macro2 = "1.0"
2222
quote = "1.0"
2323
syn = "1.0"

crates/bevy_derive/src/modules.rs

+17-15
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1+
use find_crate::Manifest;
12
use proc_macro::TokenStream;
2-
use proc_macro_crate::crate_name;
33
use syn::{Attribute, Path};
44

55
#[derive(Debug)]
@@ -12,13 +12,13 @@ pub struct Modules {
1212
}
1313

1414
impl Modules {
15-
pub fn meta() -> Modules {
15+
pub fn meta(name: &str) -> Modules {
1616
Modules {
17-
bevy_asset: "bevy::asset".to_string(),
18-
bevy_render: "bevy::render".to_string(),
19-
bevy_core: "bevy::core".to_string(),
20-
bevy_app: "bevy::app".to_string(),
21-
bevy_type_registry: "bevy::type_registry".to_string(),
17+
bevy_asset: format!("{}::asset", name),
18+
bevy_render: format!("{}::render", name),
19+
bevy_core: format!("{}::core", name),
20+
bevy_app: format!("{}::app", name),
21+
bevy_type_registry: format!("{}::type_registry", name),
2222
}
2323
}
2424

@@ -33,19 +33,21 @@ impl Modules {
3333
}
3434
}
3535

36-
fn use_meta() -> bool {
37-
crate_name("bevy").is_ok()
36+
fn get_meta() -> Option<Modules> {
37+
let manifest = Manifest::new().unwrap();
38+
if let Some(package) = manifest.find(|name| name == "bevy") {
39+
Some(Modules::meta(&package.name))
40+
} else if let Some(package) = manifest.find(|name| name == "bevy_internal") {
41+
Some(Modules::meta(&package.name))
42+
} else {
43+
None
44+
}
3845
}
3946

4047
const AS_CRATE_ATTRIBUTE_NAME: &str = "as_crate";
4148

4249
pub fn get_modules(attributes: &[Attribute]) -> Modules {
43-
let mut modules = if use_meta() {
44-
Modules::meta()
45-
} else {
46-
Modules::external()
47-
};
48-
50+
let mut modules = get_meta().unwrap_or_else(Modules::external);
4951
for attribute in attributes.iter() {
5052
if *attribute.path.get_ident().as_ref().unwrap() == AS_CRATE_ATTRIBUTE_NAME {
5153
let value = attribute.tokens.to_string();

crates/bevy_dylib/Cargo.toml

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
[package]
2+
name = "bevy_dylib"
3+
version = "0.3.0"
4+
edition = "2018"
5+
authors = [
6+
"Bevy Contributors <bevyengine@gmail.com>",
7+
"Carter Anderson <mcanders1@gmail.com>",
8+
]
9+
description = "Force the Bevy Engine to be dynamically linked for faster linking"
10+
homepage = "https://bevyengine.org"
11+
repository = "https://github.com/bevyengine/bevy"
12+
license = "MIT"
13+
keywords = ["bevy"]
14+
15+
[lib]
16+
crate-type = ["dylib"]
17+
18+
[dependencies]
19+
bevy_internal = { path = "../bevy_internal", version = "0.3.0", default-features = false }

crates/bevy_dylib/src/lib.rs

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
//! Forces dynamic linking of Bevy.
2+
//!
3+
//! Dynamically linking Bevy makes the "link" step much faster. This can be achieved by adding
4+
//! `bevy_dylib` as dependency and `#[allow(unused_imports)] use bevy_dylib` to `main.rs`. It is
5+
//! recommended to disable the `bevy_dylib` dependency in release mode by adding
6+
//! `#[cfg(debug_assertions)]` to the `use` statement. Otherwise you will have to ship `libstd.so`
7+
//! and `libbevy_dylib.so` with your game.
8+
9+
// Force linking of the main bevy crate
10+
#[allow(unused_imports)]
11+
#[allow(clippy::single_component_path_imports)]
12+
use bevy_internal;

crates/bevy_ecs/hecs/macros/Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,4 @@ proc-macro = true
1313
syn = "1.0"
1414
quote = "1.0"
1515
proc-macro2 = "1.0"
16-
proc-macro-crate = "0.1.5"
16+
find-crate = "0.5"

crates/bevy_ecs/hecs/macros/src/lib.rs

+11-9
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,9 @@ extern crate proc_macro;
1818

1919
use std::borrow::Cow;
2020

21+
use find_crate::Manifest;
2122
use proc_macro::TokenStream;
2223
use proc_macro2::{Span, TokenStream as TokenStream2};
23-
use proc_macro_crate::crate_name;
2424
use quote::quote;
2525
use syn::{
2626
parse::ParseStream, parse_macro_input, Data, DataStruct, DeriveInput, Error, Field, Fields,
@@ -54,12 +54,13 @@ fn derive_bundle_(input: DeriveInput) -> Result<TokenStream2> {
5454
}
5555
};
5656
let (tys, field_members) = struct_fields(&data.fields);
57-
let path_str = if crate_name("bevy").is_ok() {
58-
"bevy::ecs"
59-
} else if crate_name("bevy_ecs").is_ok() {
60-
"bevy_ecs"
57+
let manifest = Manifest::new().unwrap();
58+
let path_str = if let Some(package) = manifest.find(|name| name == "bevy") {
59+
format!("{}::ecs", package.name)
60+
} else if let Some(package) = manifest.find(|name| name == "bevy_ecs") {
61+
package.name
6162
} else {
62-
"bevy_hecs"
63+
"bevy_hecs".to_string()
6364
};
6465
let crate_path: Path = syn::parse(path_str.parse::<TokenStream>().unwrap()).unwrap();
6566
let field_idents = member_as_idents(&field_members);
@@ -354,10 +355,11 @@ pub fn derive_system_param(input: TokenStream) -> TokenStream {
354355
_ => panic!("expected a struct with named fields"),
355356
};
356357

357-
let path_str = if crate_name("bevy").is_ok() {
358-
"bevy::ecs"
358+
let manifest = Manifest::new().unwrap();
359+
let path_str = if let Some(package) = manifest.find(|name| name == "bevy") {
360+
format!("{}::ecs", package.name)
359361
} else {
360-
"bevy_ecs"
362+
"bevy_ecs".to_string()
361363
};
362364
let path: Path = syn::parse(path_str.parse::<TokenStream>().unwrap()).unwrap();
363365

crates/bevy_internal/Cargo.toml

+64
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
[package]
2+
name = "bevy_internal"
3+
version = "0.3.0"
4+
edition = "2018"
5+
authors = [
6+
"Bevy Contributors <bevyengine@gmail.com>",
7+
"Carter Anderson <mcanders1@gmail.com>",
8+
]
9+
description = "An internal Bevy crate used to facilitate optional dynamic linking via the 'dynamic' feature"
10+
homepage = "https://bevyengine.org"
11+
repository = "https://github.com/bevyengine/bevy"
12+
license = "MIT"
13+
keywords = ["game", "engine", "gamedev", "graphics", "bevy"]
14+
categories = ["game-engines", "graphics", "gui", "rendering"]
15+
16+
[features]
17+
profiler = ["bevy_ecs/profiler", "bevy_diagnostic/profiler"]
18+
wgpu_trace = ["bevy_wgpu/trace"]
19+
20+
# Image format support for texture loading (PNG and HDR are enabled by default)
21+
hdr = ["bevy_render/hdr"]
22+
png = ["bevy_render/png"]
23+
24+
# Audio format support (MP3 is enabled by default)
25+
flac = ["bevy_audio/flac"]
26+
mp3 = ["bevy_audio/mp3"]
27+
vorbis = ["bevy_audio/vorbis"]
28+
wav = ["bevy_audio/wav"]
29+
30+
serialize = ["bevy_input/serialize"]
31+
32+
# Display server protocol support (X11 is enabled by default)
33+
wayland = ["bevy_winit/wayland"]
34+
x11 = ["bevy_winit/x11"]
35+
36+
[dependencies]
37+
# bevy
38+
bevy_app = { path = "../bevy_app", version = "0.3.0" }
39+
bevy_asset = { path = "../bevy_asset", version = "0.3.0" }
40+
bevy_type_registry = { path = "../bevy_type_registry", version = "0.3.0" }
41+
bevy_core = { path = "../bevy_core", version = "0.3.0" }
42+
bevy_diagnostic = { path = "../bevy_diagnostic", version = "0.3.0" }
43+
bevy_ecs = { path = "../bevy_ecs", version = "0.3.0" }
44+
bevy_input = { path = "../bevy_input", version = "0.3.0" }
45+
bevy_math = { path = "../bevy_math", version = "0.3.0" }
46+
bevy_property = { path = "../bevy_property", version = "0.3.0" }
47+
bevy_scene = { path = "../bevy_scene", version = "0.3.0" }
48+
bevy_transform = { path = "../bevy_transform", version = "0.3.0" }
49+
bevy_utils = { path = "../bevy_utils", version = "0.3.0" }
50+
bevy_window = { path = "../bevy_window", version = "0.3.0" }
51+
bevy_tasks = { path = "../bevy_tasks", version = "0.3.0" }
52+
# bevy (optional)
53+
bevy_audio = { path = "../bevy_audio", optional = true, version = "0.3.0" }
54+
bevy_gltf = { path = "../bevy_gltf", optional = true, version = "0.3.0" }
55+
bevy_pbr = { path = "../bevy_pbr", optional = true, version = "0.3.0" }
56+
bevy_render = { path = "../bevy_render", optional = true, version = "0.3.0" }
57+
bevy_dynamic_plugin = { path = "../bevy_dynamic_plugin", optional = true, version = "0.3.0" }
58+
bevy_sprite = { path = "../bevy_sprite", optional = true, version = "0.3.0" }
59+
bevy_text = { path = "../bevy_text", optional = true, version = "0.3.0" }
60+
bevy_ui = { path = "../bevy_ui", optional = true, version = "0.3.0" }
61+
bevy_wgpu = { path = "../bevy_wgpu", optional = true, version = "0.3.0" }
62+
bevy_winit = { path = "../bevy_winit", optional = true, version = "0.3.0" }
63+
bevy_gilrs = { path = "../bevy_gilrs", optional = true, version = "0.3.0" }
64+
File renamed without changes.

0 commit comments

Comments
 (0)