From f9ac2ee4981313d7e1fe6b887d2121be40c58be2 Mon Sep 17 00:00:00 2001 From: Zhang Junyang Date: Sat, 13 Apr 2024 20:11:32 +0800 Subject: [PATCH] Fix OSDK feature selection --- osdk/src/base_crate/mod.rs | 47 ++++++++++++++++++++++++++++---- osdk/src/cli.rs | 4 ++- osdk/src/commands/build/mod.rs | 23 ++++++++++------ osdk/src/config/manifest.rs | 4 +-- osdk/src/config/mod.rs | 3 ++ osdk/src/config/scheme/action.rs | 7 +++++ 6 files changed, 72 insertions(+), 16 deletions(-) diff --git a/osdk/src/base_crate/mod.rs b/osdk/src/base_crate/mod.rs index 36152423c..d4a54bff3 100644 --- a/osdk/src/base_crate/mod.rs +++ b/osdk/src/base_crate/mod.rs @@ -26,7 +26,7 @@ pub fn new_base_crate( std::fs::remove_dir_all(&base_crate_path).unwrap(); } - let dep_crate_version = { + let (dep_crate_version, dep_crate_features) = { let cargo_toml = dep_crate_path.as_ref().join("Cargo.toml"); let cargo_toml = fs::read_to_string(cargo_toml).unwrap(); let cargo_toml: toml::Value = toml::from_str(&cargo_toml).unwrap(); @@ -38,8 +38,13 @@ pub fn new_base_crate( .get("version") .unwrap() .as_str() - .unwrap(); - dep_version.to_string() + .unwrap() + .to_string(); + let dep_features = cargo_toml + .get("features") + .map(|f| f.as_table().unwrap().clone()) + .unwrap_or_default(); + (dep_version, dep_features) }; // Create the directory @@ -82,6 +87,9 @@ pub fn new_base_crate( // Copy the manifest configurations from the target crate to the base crate copy_profile_configurations(workspace_root); + // Generate the features by copying the features from the target crate + add_feature_entries(dep_crate_name, &dep_crate_features); + // Get back to the original directory std::env::set_current_dir(original_dir).unwrap(); } @@ -105,7 +113,7 @@ fn add_manifest_dependency(crate_name: &str, crate_path: impl AsRef) { let dependencies = manifest.get_mut("dependencies").unwrap(); let dep = toml::Table::from_str(&format!( - "{} = {{ path = \"{}\"}}", + "{} = {{ path = \"{}\", default-features = false }}", crate_name, crate_path.as_ref().display() )) @@ -133,9 +141,38 @@ fn copy_profile_configurations(workspace_root: impl AsRef) { // Copy the profile configurations let profile = target_manifest.get("profile"); if let Some(profile) = profile { - manifest.insert("profile".to_string(), profile.clone()); + manifest.insert( + "profile".to_string(), + toml::Value::Table(profile.as_table().unwrap().clone()), + ); } let content = toml::to_string(&manifest).unwrap(); fs::write(manifest_path, content).unwrap(); } + +fn add_feature_entries(dep_crate_name: &str, features: &toml::Table) { + let manifest_path = "Cargo.toml"; + let mut manifest: toml::Table = { + let content = fs::read_to_string(manifest_path).unwrap(); + toml::from_str(&content).unwrap() + }; + + let mut table = toml::Table::new(); + for (feature, value) in features.iter() { + let value = if feature != &"default".to_string() { + vec![toml::Value::String(format!( + "{}/{}", + dep_crate_name, feature + ))] + } else { + value.as_array().unwrap().clone() + }; + table.insert(feature.clone(), toml::Value::Array(value)); + } + + manifest.insert("features".to_string(), toml::Value::Table(table)); + + let content = toml::to_string(&manifest).unwrap(); + fs::write(manifest_path, content).unwrap(); +} diff --git a/osdk/src/cli.rs b/osdk/src/cli.rs index fc255efcf..84cefb982 100644 --- a/osdk/src/cli.rs +++ b/osdk/src/cli.rs @@ -26,7 +26,7 @@ pub fn main() { }; let load_config = || { - let manifest = TomlManifest::load(&common_args.build_args.features); + let manifest = TomlManifest::load(); let scheme = manifest.get_scheme(common_args.scheme.as_ref()); Config::new(scheme, &common_args) }; @@ -233,6 +233,8 @@ pub struct CargoArgs { global = true, )] pub features: Vec, + #[arg(long, help = "Do not activate the `default` features", global = true)] + pub no_default_features: bool, } impl CargoArgs { diff --git a/osdk/src/commands/build/mod.rs b/osdk/src/commands/build/mod.rs index f6feb7079..66a11456e 100644 --- a/osdk/src/commands/build/mod.rs +++ b/osdk/src/commands/build/mod.rs @@ -143,20 +143,20 @@ pub fn do_build( } let mut bundle = Bundle::new(&bundle_path, config, action); - info!("Building kernel ELF"); + let (build, boot) = match action { + ActionChoice::Run => (&config.run.build, &config.run.boot), + ActionChoice::Test => (&config.test.build, &config.test.boot), + }; + let aster_elf = build_kernel_elf( &config.target_arch, - &config.build.profile, - &config.build.features[..], + &build.profile, + &build.features[..], + build.no_default_features, &cargo_target_directory, rustflags, ); - let boot = match action { - ActionChoice::Run => &config.run.boot, - ActionChoice::Test => &config.test.boot, - }; - match boot.method { BootMethod::GrubRescueIso => { info!("Building boot device image"); @@ -185,6 +185,7 @@ fn build_kernel_elf( arch: &Arch, profile: &str, features: &[String], + no_default_features: bool, cargo_target_directory: impl AsRef, rustflags: &[&str], ) -> AsterBin { @@ -209,12 +210,18 @@ fn build_kernel_elf( command.env("RUSTFLAGS", rustflags.join(" ")); command.arg("build"); command.arg("--features").arg(features.join(" ")); + if no_default_features { + command.arg("--no-default-features"); + } command.arg("--target").arg(&target_os_string); command .arg("--target-dir") .arg(cargo_target_directory.as_ref()); command.args(COMMON_CARGO_ARGS); command.arg("--profile=".to_string() + profile); + + info!("Building kernel ELF using command: {:#?}", command); + let status = command.status().unwrap(); if !status.success() { error_msg!("Cargo build failed"); diff --git a/osdk/src/config/manifest.rs b/osdk/src/config/manifest.rs index c07f4acad..6488473c5 100644 --- a/osdk/src/config/manifest.rs +++ b/osdk/src/config/manifest.rs @@ -38,9 +38,9 @@ pub struct TomlManifest { } impl TomlManifest { - pub fn load(feature_strings: &Vec) -> Self { + pub fn load() -> Self { let workspace_root = { - let cargo_metadata = get_cargo_metadata(None::<&str>, Some(feature_strings)).unwrap(); + let cargo_metadata = get_cargo_metadata(None::<&str>, None::<&[&str]>).unwrap(); PathBuf::from( cargo_metadata .get("workspace_root") diff --git a/osdk/src/config/mod.rs b/osdk/src/config/mod.rs index 764ce9e17..8eb21d053 100644 --- a/osdk/src/config/mod.rs +++ b/osdk/src/config/mod.rs @@ -42,6 +42,9 @@ fn apply_args_before_finalize(action_scheme: &mut ActionScheme, args: &CommonArg build.profile = Some(profile.clone()); } build.features.extend(args.build_args.features.clone()); + if args.build_args.no_default_features { + build.no_default_features = true; + } if args.linux_x86_legacy_boot { build.linux_x86_legacy_boot = true; } diff --git a/osdk/src/config/scheme/action.rs b/osdk/src/config/scheme/action.rs index 6e4a997fc..ee97dcc93 100644 --- a/osdk/src/config/scheme/action.rs +++ b/osdk/src/config/scheme/action.rs @@ -14,6 +14,8 @@ pub enum ActionChoice { pub struct BuildScheme { pub profile: Option, pub features: Vec, + #[serde(default)] + pub no_default_features: bool, /// Whether to turn on the support for the /// [Linux legacy x86 32-bit boot protocol](https://www.kernel.org/doc/html/v5.6/x86/boot.html) #[serde(default)] @@ -25,6 +27,8 @@ pub struct Build { pub profile: String, pub features: Vec, #[serde(default)] + pub no_default_features: bool, + #[serde(default)] pub linux_x86_legacy_boot: bool, } @@ -33,6 +37,7 @@ impl Default for Build { Self { profile: "dev".to_string(), features: Vec::new(), + no_default_features: false, linux_x86_legacy_boot: false, } } @@ -48,6 +53,7 @@ impl BuildScheme { features.extend(self.features.clone()); features }; + // no_default_features is not inherited if parent.linux_x86_legacy_boot { self.linux_x86_legacy_boot = true; } @@ -57,6 +63,7 @@ impl BuildScheme { Build { profile: self.profile.unwrap_or_else(|| "dev".to_string()), features: self.features, + no_default_features: self.no_default_features, linux_x86_legacy_boot: self.linux_x86_legacy_boot, } }