Use separate crate to compile anim as a cdylib to avoid compiling both all the time and improve voxygen pipelining

This commit is contained in:
Imbris 2021-04-16 19:22:06 -04:00
parent c83c1a5571
commit 30e34aad44
7 changed files with 84 additions and 38 deletions

7
Cargo.lock generated
View File

@ -5775,6 +5775,13 @@ dependencies = [
"veloren-common", "veloren-common",
] ]
[[package]]
name = "veloren-voxygen-anim-dyn"
version = "0.9.0"
dependencies = [
"veloren-voxygen-anim",
]
[[package]] [[package]]
name = "veloren-world" name = "veloren-world"
version = "0.9.0" version = "0.9.0"

View File

@ -16,6 +16,7 @@ members = [
"server-cli", "server-cli",
"voxygen", "voxygen",
"voxygen/anim", "voxygen/anim",
"voxygen/anim/dyn",
"world", "world",
"network", "network",
"network/protocol" "network/protocol"

View File

@ -27,7 +27,7 @@ common-frontend = {package = "veloren-common-frontend", path = "../common/fronte
common-net = {package = "veloren-common-net", path = "../common/net"} common-net = {package = "veloren-common-net", path = "../common/net"}
common-sys = {package = "veloren-common-sys", path = "../common/sys"} common-sys = {package = "veloren-common-sys", path = "../common/sys"}
anim = {package = "veloren-voxygen-anim", path = "anim", default-features = false} anim = {package = "veloren-voxygen-anim", path = "anim"}
# Graphics # Graphics
gfx = "0.18.2" gfx = "0.18.2"

View File

@ -4,18 +4,12 @@ edition = "2018"
name = "veloren-voxygen-anim" name = "veloren-voxygen-anim"
version = "0.9.0" version = "0.9.0"
[lib]
name = "voxygen_anim"
# Uncomment to use animation hot reloading
# Note: this breaks `cargo test`
crate-type = ["lib", "cdylib"]
[features] [features]
be-dyn-lib = []
use-dyn-lib = ["libloading", "notify", "lazy_static", "tracing", "find_folder"] use-dyn-lib = ["libloading", "notify", "lazy_static", "tracing", "find_folder"]
be-dyn-lib = []
simd = ["vek/platform_intrinsics"] simd = ["vek/platform_intrinsics"]
default = ["be-dyn-lib", "simd"] default = ["simd"]
[dependencies] [dependencies]
common = {package = "veloren-common", path = "../../common"} common = {package = "veloren-common", path = "../../common"}

View File

@ -0,0 +1,17 @@
[package]
authors = ["Imbris <imbrisf@gmail.com>"]
edition = "2018"
name = "veloren-voxygen-anim-dyn"
version = "0.9.0"
[lib]
# Using dylib instead of cdylib increases the size 3 -> 13 mb
# but it is needed to expose the symbols from the anim crate :(
# effect on compile time appears to be insignificant
crate-type = ["dylib"]
[features]
be-dyn-lib = ["veloren-voxygen-anim/be-dyn-lib"]
[dependencies]
veloren-voxygen-anim = { path = "../" }

View File

@ -0,0 +1,14 @@
//! This crate hacks around the inability to dynamically specify the
//! `crate-type` for cargo to build.
//!
//! For more details on the issue this is a decent starting point: https://github.com/rust-lang/cargo/pull/8789
//!
//! This crate avoids use building the dynamic lib when it isn't needed and the
//! same with the non dynamic build. Additionally, this allows compilation to
//! start earlier since a cdylib doesn't pipeline with it's dependencies.
//!
//! NOTE: the `be-dyn-lib` feature must be used for this crate to be useful, it
//! is not on by default becaue this causes cargo to switch the feature on in
//! the anim crate when compiling the static lib into voxygen.
#[cfg(feature = "be-dyn-lib")]
pub use veloren_voxygen_anim::*;

View File

@ -4,7 +4,6 @@ use notify::{immediate_watcher, EventKind, RecursiveMode, Watcher};
use std::{ use std::{
process::{Command, Stdio}, process::{Command, Stdio},
sync::{mpsc, Mutex}, sync::{mpsc, Mutex},
thread,
time::Duration, time::Duration,
}; };
@ -13,14 +12,14 @@ use std::{env, path::PathBuf};
use tracing::{debug, error, info}; use tracing::{debug, error, info};
#[cfg(target_os = "windows")] #[cfg(target_os = "windows")]
const COMPILED_FILE: &str = "voxygen_anim.dll"; const COMPILED_FILE: &str = "veloren_voxygen_anim_dyn.dll";
#[cfg(target_os = "windows")] #[cfg(target_os = "windows")]
const ACTIVE_FILE: &str = "voxygen_anim_active.dll"; const ACTIVE_FILE: &str = "veloren_voxygen_anim_dyn_active.dll";
#[cfg(not(target_os = "windows"))] #[cfg(not(target_os = "windows"))]
const COMPILED_FILE: &str = "libvoxygen_anim.so"; const COMPILED_FILE: &str = "libveloren_voxygen_anim_dyn.so";
#[cfg(not(target_os = "windows"))] #[cfg(not(target_os = "windows"))]
const ACTIVE_FILE: &str = "libvoxygen_anim_active.so"; const ACTIVE_FILE: &str = "libveloren_voxygen_anim_dyn_active.so";
// This option is required as `hotreload()` moves the `LoadedLib`. // This option is required as `hotreload()` moves the `LoadedLib`.
lazy_static! { lazy_static! {
@ -29,7 +28,7 @@ lazy_static! {
/// LoadedLib holds a loaded dynamic library and the location of library file /// LoadedLib holds a loaded dynamic library and the location of library file
/// with the appropriate OS specific name and extension i.e. /// with the appropriate OS specific name and extension i.e.
/// `libvoxygen_anim_active.dylib`, `voxygen_anim_active.dll`. /// `libvoxygen_anim_dyn_active.dylib`, `voxygen_anim_dyn_active.dll`.
/// ///
/// # NOTE /// # NOTE
/// DOES NOT WORK ON MACOS, due to some limitations with hot-reloading the /// DOES NOT WORK ON MACOS, due to some limitations with hot-reloading the
@ -74,10 +73,8 @@ impl LoadedLib {
let lib = match unsafe { Library::new(lib_path.clone()) } { let lib = match unsafe { Library::new(lib_path.clone()) } {
Ok(lib) => lib, Ok(lib) => lib,
Err(e) => panic!( Err(e) => panic!(
"Tried to load dynamic library from {:?}, but it could not be found. The first \ "Tried to load dynamic library from {:?}, but it could not be found. A potential \
reason might be that you need to uncomment a line in `voxygen/anim/Cargo.toml` \ reason is we may require a special case for your OS so we can find it. {:?}",
to build the library required for hot reloading. The second is we may require a \
special case for your OS so we can find it. {:?}",
lib_path, e lib_path, e
), ),
}; };
@ -141,28 +138,37 @@ pub fn init() {
// Start watcher // Start watcher
let mut watcher = immediate_watcher(move |res| event_fn(res, &reload_send)).unwrap(); let mut watcher = immediate_watcher(move |res| event_fn(res, &reload_send)).unwrap();
watcher.watch("anim", RecursiveMode::Recursive).unwrap();
// Search for the anim directory.
let anim_dir = Search::Kids(1)
.for_folder("anim")
.expect("Could not find the anim crate directory relative to the current directory");
watcher.watch(anim_dir, RecursiveMode::Recursive).unwrap();
// Start reloader that watcher signals // Start reloader that watcher signals
// "Debounces" events since I can't find the option to do this in the latest // "Debounces" events since I can't find the option to do this in the latest
// `notify` // `notify`
std::thread::Builder::new("voxygen_anim_watcher".to_owned()).spawn(move || { std::thread::Builder::new()
let mut modified_paths = std::collections::HashSet::new(); .name("voxygen_anim_watcher".into())
while let Ok(path) = reload_recv.recv() { .spawn(move || {
modified_paths.insert(path); let mut modified_paths = std::collections::HashSet::new();
// Wait for any additional modify events before reloading while let Ok(path) = reload_recv.recv() {
while let Ok(path) = reload_recv.recv_timeout(Duration::from_millis(300)) {
modified_paths.insert(path); modified_paths.insert(path);
// Wait for any additional modify events before reloading
while let Ok(path) = reload_recv.recv_timeout(Duration::from_millis(300)) {
modified_paths.insert(path);
}
info!(
?modified_paths,
"Hot reloading animations because files in `anim` modified."
);
hotreload();
} }
})
info!( .unwrap();
?modified_paths,
"Hot reloading animations because files in `anim` modified."
);
hotreload();
}
});
// Let the watcher live forever // Let the watcher live forever
std::mem::forget(watcher); std::mem::forget(watcher);
@ -220,7 +226,9 @@ fn compile() -> bool {
.stdout(Stdio::inherit()) .stdout(Stdio::inherit())
.arg("build") .arg("build")
.arg("--package") .arg("--package")
.arg("veloren-voxygen-anim") .arg("veloren-voxygen-anim-dyn")
.arg("--features")
.arg("veloren-voxygen-anim-dyn/be-dyn-lib")
.output() .output()
.unwrap(); .unwrap();
@ -241,5 +249,10 @@ fn copy(lib_path: &PathBuf) {
// Copy the library file from where it is output, to where we are going to // Copy the library file from where it is output, to where we are going to
// load it from i.e. lib_path. // load it from i.e. lib_path.
std::fs::copy(lib_compiled_path, lib_output_path).expect("Failed to rename dynamic library."); std::fs::copy(&lib_compiled_path, &lib_output_path).unwrap_or_else(|err| {
panic!(
"Failed to rename dynamic library from {:?} to {:?}. {:?}",
lib_compiled_path, lib_output_path, err
)
});
} }