From 305cda33362b3e9341604075a3d182900cf7f354 Mon Sep 17 00:00:00 2001 From: Jiahao XU Date: Sat, 27 Aug 2022 21:27:39 +1000 Subject: [PATCH] Optimize compilation time (#320) * Print `rerun-if-changed=build.rs` in `build.rs` * Optimize compile-time: Extract `bin/src/lib.rs` so that `cargo-binstall (lib)` can be compiled in parallel to other deps. * Refactor: Extract new mod `bin/src/bin_utils.rs` * Extract new fn `MainExit::new` * Refactor: Extract new fn `run_tokio_main` * Handle `Runtime::new` err gracefully in `run_tokio_main` instead of `panic!`ing, return the error as `BinstallError` * Avoid mixing `eprintln` and `error` in `MainExit::report` * Set profile for `build-override` to speedup building of `build.rs` and proc macros. Signed-off-by: Jiahao XU --- Cargo.toml | 16 +++++++++ crates/bin/build.rs | 2 ++ crates/bin/src/bin_util.rs | 60 ++++++++++++++++++++++++++++++++ crates/bin/src/lib.rs | 5 +++ crates/bin/src/main.rs | 63 ++++++---------------------------- crates/detect-targets/build.rs | 2 ++ 6 files changed, 95 insertions(+), 53 deletions(-) create mode 100644 crates/bin/src/bin_util.rs create mode 100644 crates/bin/src/lib.rs diff --git a/Cargo.toml b/Cargo.toml index 8cbee532..0e1c817a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,3 +14,19 @@ lto = true codegen-units = 1 panic = "abort" strip = "symbols" + +[profile.dev.build-override] +opt-level = 0 +codegen-units = 1024 +debug = false +debug-assertions = false +overflow-checks = false +incremental = false + +[profile.release.build-override] +opt-level = 0 +codegen-units = 1024 +debug = false +debug-assertions = false +overflow-checks = false +incremental = false diff --git a/crates/bin/build.rs b/crates/bin/build.rs index b7db24d6..e3f7605b 100644 --- a/crates/bin/build.rs +++ b/crates/bin/build.rs @@ -1,3 +1,5 @@ fn main() { + println!("cargo:rerun-if-changed=build.rs"); + embed_resource::compile("manifest.rc"); } diff --git a/crates/bin/src/bin_util.rs b/crates/bin/src/bin_util.rs new file mode 100644 index 00000000..783d8419 --- /dev/null +++ b/crates/bin/src/bin_util.rs @@ -0,0 +1,60 @@ +use std::{ + future::Future, + process::{ExitCode, Termination}, + time::Duration, +}; + +use binstall::errors::BinstallError; +use binstall::helpers::{signal::cancel_on_user_sig_term, tasks::AutoAbortJoinHandle}; +use log::{error, info}; +use miette::Result; +use tokio::runtime::Runtime; + +pub enum MainExit { + Success(Duration), + Error(BinstallError), + Report(miette::Report), +} + +impl Termination for MainExit { + fn report(self) -> ExitCode { + match self { + Self::Success(spent) => { + info!("Done in {spent:?}"); + ExitCode::SUCCESS + } + Self::Error(err) => err.report(), + Self::Report(err) => { + error!("Fatal error:\n{err:?}"); + ExitCode::from(16) + } + } + } +} + +impl MainExit { + pub fn new(result: Result, BinstallError>, done: Duration) -> Self { + result.map_or_else(MainExit::Error, |res| { + res.map(|()| MainExit::Success(done)).unwrap_or_else(|err| { + err.downcast::() + .map(MainExit::Error) + .unwrap_or_else(MainExit::Report) + }) + }) + } +} + +/// This function would start a tokio multithreading runtime, +/// spawn a new task on it that runs `f`, then `block_on` it. +/// +/// It will cancel the future if user requested cancellation +/// via signal. +pub fn run_tokio_main(f: F) -> Result +where + F: Future + Send + 'static, + T: Send + 'static, +{ + let rt = Runtime::new()?; + let handle = AutoAbortJoinHandle::new(rt.spawn(f)); + rt.block_on(cancel_on_user_sig_term(handle)) +} diff --git a/crates/bin/src/lib.rs b/crates/bin/src/lib.rs new file mode 100644 index 00000000..4f443dbe --- /dev/null +++ b/crates/bin/src/lib.rs @@ -0,0 +1,5 @@ +pub mod args; +pub mod bin_util; +pub mod entry; +pub mod install_path; +pub mod ui; diff --git a/crates/bin/src/main.rs b/crates/bin/src/main.rs index d02828d2..374233de 100644 --- a/crates/bin/src/main.rs +++ b/crates/bin/src/main.rs @@ -1,22 +1,13 @@ -use std::{ - process::{ExitCode, Termination}, - time::{Duration, Instant}, -}; +use std::time::Instant; -use binstall::{ - errors::BinstallError, - helpers::{ - jobserver_client::LazyJobserverClient, signal::cancel_on_user_sig_term, - tasks::AutoAbortJoinHandle, - }, -}; -use log::{debug, error, info}; -use tokio::runtime::Runtime; +use binstall::helpers::jobserver_client::LazyJobserverClient; +use log::debug; -mod args; -mod entry; -mod install_path; -mod ui; +use cargo_binstall::{ + args, + bin_util::{run_tokio_main, MainExit}, + entry, ui, +}; #[cfg(feature = "mimalloc")] #[global_allocator] @@ -35,44 +26,10 @@ fn main() -> MainExit { let start = Instant::now(); - let result = { - let rt = Runtime::new().unwrap(); - let handle = - AutoAbortJoinHandle::new(rt.spawn(entry::install_crates(args, jobserver_client))); - rt.block_on(cancel_on_user_sig_term(handle)) - }; + let result = run_tokio_main(entry::install_crates(args, jobserver_client)); let done = start.elapsed(); debug!("run time: {done:?}"); - result.map_or_else(MainExit::Error, |res| { - res.map(|()| MainExit::Success(done)).unwrap_or_else(|err| { - err.downcast::() - .map(MainExit::Error) - .unwrap_or_else(MainExit::Report) - }) - }) -} - -enum MainExit { - Success(Duration), - Error(BinstallError), - Report(miette::Report), -} - -impl Termination for MainExit { - fn report(self) -> ExitCode { - match self { - Self::Success(spent) => { - info!("Done in {spent:?}"); - ExitCode::SUCCESS - } - Self::Error(err) => err.report(), - Self::Report(err) => { - error!("Fatal error:"); - eprintln!("{err:?}"); - ExitCode::from(16) - } - } - } + MainExit::new(result, done) } diff --git a/crates/detect-targets/build.rs b/crates/detect-targets/build.rs index 729c4c54..15152d41 100644 --- a/crates/detect-targets/build.rs +++ b/crates/detect-targets/build.rs @@ -1,4 +1,6 @@ fn main() { + println!("cargo:rerun-if-changed=build.rs"); + // Fetch build target and define this for the compiler println!( "cargo:rustc-env=TARGET={}",