From 376527a58467c6e723085a9047317b0fdd5c3f6f Mon Sep 17 00:00:00 2001 From: Ybeichen Date: Mon, 1 Jan 2024 12:39:46 +0800 Subject: [PATCH] Multithreaded builds OS and ulib --- Cargo.lock | 11 +++++++++++ Cargo.toml | 3 ++- src/commands.rs | 47 +++++++++++++++++++++++++++++++++-------------- src/features.rs | 2 +- src/utils.rs | 6 +++--- 5 files changed, 50 insertions(+), 19 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 48cc266..2651c78 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -418,6 +418,16 @@ dependencies = [ "autocfg", ] +[[package]] +name = "num_cpus" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" +dependencies = [ + "hermit-abi", + "libc", +] + [[package]] name = "number_prefix" version = "0.4.0" @@ -517,6 +527,7 @@ dependencies = [ "directories", "indicatif", "itertools", + "num_cpus", "rayon", "serde", "sha1", diff --git a/Cargo.toml b/Cargo.toml index 0dc3c3f..70bee56 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,4 +19,5 @@ indicatif = "0.17.3" clap = { version = "4.4.11", features = ["derive"] } directories = "5.0.1" serde = { version = "1.0.190", features = ["derive"] } -dialoguer = "0.11.0" \ No newline at end of file +dialoguer = "0.11.0" +num_cpus = "1.16.0" \ No newline at end of file diff --git a/src/commands.rs b/src/commands.rs index 56de740..5bf0beb 100644 --- a/src/commands.rs +++ b/src/commands.rs @@ -6,6 +6,7 @@ use std::path::Path; use std::io::Write; use std::fs; use std::process::{Command, Stdio}; +extern crate num_cpus; static ROOT_DIR: &str = "ruxos_bld"; static BUILD_DIR: &str = "ruxos_bld/bin"; @@ -342,18 +343,32 @@ pub fn build( // Construct os and ulib if os_config != &OSConfig::default() { + log(LogLevel::Log, &format!("Compiling OS: {}, Ulib: {} ", os_config.name, os_config.ulib)); let (rux_feats_final, lib_feats_final) = features::cfg_feat_addprefix(os_config); - if os_config.ulib == "ruxlibc" { - log(LogLevel::Log, &format!("Compiling OS: {}", os_config.name)); - build_os(&os_config, &os_config.ulib, &rux_feats_final, &lib_feats_final); - log(LogLevel::Log, &format!("Compiling Ulib: {}", os_config.ulib)); - build_ruxlibc(build_config, os_config, gen_cc); - } else if os_config.ulib == "ruxmusl" { - log(LogLevel::Log, &format!("Compiling OS: {}", os_config.name)); - build_os(&os_config, &os_config.ulib, &rux_feats_final, &lib_feats_final); - log(LogLevel::Log, &format!("Compiling Ulib: {}", os_config.ulib)); - build_ruxmusl(build_config, os_config); - } + + // thread os + let os_config_clone = os_config.clone(); + let rux_feats_final_clone = rux_feats_final.clone(); + let lib_feats_final_clone = lib_feats_final.clone(); + let thread_os = std::thread::spawn(move || { + build_os(&os_config_clone, &os_config_clone.ulib, &rux_feats_final_clone, &lib_feats_final_clone); + }); + + // thread ulib + let build_config_clone = build_config.clone(); + let os_config_clone_ = os_config.clone(); + let gen_cc_clone = gen_cc.clone(); + let thread_ulib = std::thread::spawn(move || { + if os_config_clone_.ulib == "ruxlibc" { + build_ruxlibc(&build_config_clone, &os_config_clone_, gen_cc_clone); + } else if os_config_clone_.ulib == "ruxmusl" { + build_ruxmusl(&build_config_clone, &os_config_clone_); + } + }); + + // join thread + thread_os.join().expect("Thread OS panicked"); + thread_ulib.join().expect("Thread Ulib panicked"); }; // Construct each target separately @@ -394,9 +409,13 @@ fn build_os(os_config: &OSConfig, ulib: &str, rux_feats: &Vec, lib_feats }; // add features let features = [&rux_feats[..], &lib_feats[..]].concat().join(" "); + // number of parallel jobs + let num_cores = num_cpus::get(); + log(LogLevel::Debug, &format!("Num_cores: {}", num_cores)); + // cmd let cmd = format!( - "cargo build {} {} {} {} {} --features \"{}\"", - target, target_dir, mode, os_ulib, verbose, features + "cargo build {} {} {} {} {} --features \"{}\" -j {}", + target, target_dir, mode, os_ulib, verbose, features, num_cores ); log(LogLevel::Info, &format!("Command: {}", cmd)); let output = Command::new("sh") @@ -486,7 +505,7 @@ fn build_ruxmusl(build_config: &BuildConfig, os_config: &OSConfig) { } // compile and install ruxmusl - log(LogLevel::Log, "Musl source code is installing..."); + log(LogLevel::Log, "Compiling and installing Musl..."); let make_output = Command::new("make") .args(&["-j"]) .current_dir(RUXMUSL_DIR) diff --git a/src/features.rs b/src/features.rs index b879075..c302284 100644 --- a/src/features.rs +++ b/src/features.rs @@ -47,7 +47,7 @@ pub fn cfg_feat_addprefix(os_config: &OSConfig) -> (Vec, Vec) { "ruxlibc" => "ruxlibc/", "ruxmusl" => "ruxmusl/", _ => { - log(LogLevel::Error, "Invalid ulib value"); + log(LogLevel::Error, "Ulib must be one of \"ruxlibc\" or \"ruxmusl\""); std::process::exit(1); } }; diff --git a/src/utils.rs b/src/utils.rs index 692da1a..5b881e1 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -78,7 +78,7 @@ pub struct BuildConfig { } /// Struct descibing the OS config of the local project -#[derive(Debug, Default, PartialEq)] +#[derive(Debug, Default, PartialEq, Clone)] pub struct OSConfig { pub name: String, pub features: Vec, @@ -87,7 +87,7 @@ pub struct OSConfig { } /// Struct descibing the platform config of the local project -#[derive(Debug, Default, PartialEq)] +#[derive(Debug, Default, PartialEq, Clone)] pub struct PlatformConfig { pub name: String, pub arch: String, @@ -101,7 +101,7 @@ pub struct PlatformConfig { } /// Struct descibing the qemu config of the local project -#[derive(Debug, Default, PartialEq)] +#[derive(Debug, Default, PartialEq, Clone)] pub struct QemuConfig { pub debug: String, pub blk: String,