From 9239005bf64818d34ef544a1f56128c0567d170b Mon Sep 17 00:00:00 2001 From: Wildan M Date: Fri, 7 Nov 2025 14:01:33 +0700 Subject: [PATCH 1/4] Recurse build deps in sysroot --- src/bin/cook.rs | 29 +++++------ src/bin/repo.rs | 13 ++--- src/cook/cook_build.rs | 51 +++++++++++++------- src/recipe.rs | 107 ++++++++++++++++++++++++++++++----------- 4 files changed, 131 insertions(+), 69 deletions(-) diff --git a/src/bin/cook.rs b/src/bin/cook.rs index 1f5a4f332..555fd37a0 100644 --- a/src/bin/cook.rs +++ b/src/bin/cook.rs @@ -89,20 +89,21 @@ fn main() { }; } - let recipes = match CookRecipe::get_build_deps_recursive(&recipe_names, !with_package_deps) { - Ok(ok) => ok, - Err(err) => { - eprintln!( - "{}{}cook - error:{}{} {}", - style::Bold, - color::Fg(color::AnsiValue(196)), - color::Fg(color::Reset), - style::Reset, - err, - ); - process::exit(1); - } - }; + let recipes = + match CookRecipe::get_build_deps_recursive(&recipe_names, true, !with_package_deps) { + Ok(ok) => ok, + Err(err) => { + eprintln!( + "{}{}cook - error:{}{} {}", + style::Bold, + color::Fg(color::AnsiValue(196)), + color::Fg(color::Reset), + style::Reset, + err, + ); + process::exit(1); + } + }; for recipe in recipes { if !quiet { diff --git a/src/bin/repo.rs b/src/bin/repo.rs index 2d08507c1..8fe2700e6 100644 --- a/src/bin/repo.rs +++ b/src/bin/repo.rs @@ -9,7 +9,7 @@ use cookbook::cook::pty::{PtyOut, UnixSlavePty, flush_pty, setup_pty}; use cookbook::cook::script::KILL_ALL_PID; use cookbook::cook::tree::{display_tree_entry, format_size}; use cookbook::log_to_pty; -use cookbook::recipe::{BuildKind, CookRecipe}; +use cookbook::recipe::CookRecipe; use pkg::PackageName; use pkg::package::PackageError; use ratatui::Terminal; @@ -418,6 +418,7 @@ fn parse_args(args: Vec) -> anyhow::Result<(CliConfig, CliCommand, Vec) -> anyhow::Result<(CliConfig, CliCommand, Vec { recipe.recipe.source = None; - recipe.recipe.build = cookbook::recipe::BuildRecipe { - kind: BuildKind::Remote, - dependencies: Vec::new(), - }; + recipe.recipe.build.set_as_remote(); } PackageConfig::Build(rule) => { return Err(anyhow!( @@ -458,10 +456,7 @@ fn parse_args(args: Vec) -> anyhow::Result<(CliConfig, CliCommand, Vec, dynamic_dep_pkgars: &BTreeSet, -) -> Result, PackageError> { +) -> Result<(BTreeSet, Vec), PackageError> { let static_dep_pkgars: Vec = build_dep_pkgars .iter() .map(|x| x.0.clone()) @@ -157,7 +156,7 @@ fn auto_deps_from_static_package_deps( .collect(); let pkgs = CookRecipe::get_package_deps_recursive(&static_dep_pkgars, false)?; - Ok(pkgs.into_iter().collect()) + Ok((pkgs.into_iter().collect(), static_dep_pkgars)) } pub fn build( @@ -178,15 +177,13 @@ pub fn build( } let mut dep_pkgars = BTreeSet::new(); - for dependency in recipe.build.dependencies.iter() { - let dependency_dir = recipes::find(dependency.as_str()); - if dependency_dir.is_none() { - return Err(format!("failed to find recipe directory '{}'", dependency)); - } + let build_deps = CookRecipe::get_build_deps_recursive(&recipe.build.dependencies, false, false) + .map_err(|e| format!("{:?}", e))?; + for dependency in build_deps.iter() { dep_pkgars.insert(( - dependency.clone(), - dependency_dir - .unwrap() + dependency.name.clone(), + dependency + .dir .join("target") .join(redoxer::target()) .join("stage.pkgar"), @@ -194,7 +191,7 @@ pub fn build( } if stage_dir.exists() && !check_source { - let auto_deps = build_auto_deps(target_dir, &stage_dir, dep_pkgars, logger)?; + let auto_deps = build_auto_deps(recipe, target_dir, &stage_dir, dep_pkgars, logger)?; return Ok((stage_dir, auto_deps)); } @@ -370,13 +367,14 @@ pub fn build( rename(&stage_dir_tmp, &stage_dir)?; } - let auto_deps = build_auto_deps(target_dir, &stage_dir, dep_pkgars, logger)?; + let auto_deps = build_auto_deps(recipe, target_dir, &stage_dir, dep_pkgars, logger)?; Ok((stage_dir, auto_deps)) } /// Calculate automatic dependencies fn build_auto_deps( + recipe: &Recipe, target_dir: &Path, stage_dir: &PathBuf, dep_pkgars: BTreeSet<(PackageName, PathBuf)>, @@ -394,12 +392,29 @@ fn build_auto_deps( toml::from_str(&toml_content).map_err(|_| "failed to deserialize cached auto_deps")?; wrapper.packages } else { - let mut packages1 = auto_deps_from_dynamic_linking(stage_dir, &dep_pkgars, logger); - let packages2 = - auto_deps_from_static_package_deps(&dep_pkgars, &packages1).unwrap_or_default(); - packages1.extend(packages2); + let mut dynamic_deps = auto_deps_from_dynamic_linking(stage_dir, &dep_pkgars, logger); + let (package_deps, static_deps) = + auto_deps_from_static_package_deps(&dep_pkgars, &dynamic_deps).unwrap_or_default(); + dynamic_deps.extend(package_deps); + + // if auto_deps working, all build deps should be linked as auto_deps, otherwise: + // 1. it's weakly linked, which should be mentioned as package deps + // 2. it's not our direct ELF dependencies, which should be removed from build deps + // 3. only needed for build purpose, which should be moved to dev build deps + if dynamic_deps.len() > 0 && static_deps.len() > 0 { + for dep in &static_deps { + if !recipe.package.dependencies.contains(dep) { + log_to_pty!( + &logger, + "WARNING: build deps {} is not linked in auto_deps", + dep.as_str() + ); + } + } + } + let wrapper = AutoDeps { - packages: packages1, + packages: dynamic_deps, }; serialize_and_write(&auto_deps_path, &wrapper)?; wrapper.packages diff --git a/src/recipe.rs b/src/recipe.rs index 3c9095fd7..153be4076 100644 --- a/src/recipe.rs +++ b/src/recipe.rs @@ -140,6 +140,8 @@ pub struct BuildRecipe { pub kind: BuildKind, #[serde(default)] pub dependencies: Vec, + #[serde(default, rename = "dev-dependencies")] + pub dev_dependencies: Vec, } #[derive(Debug, Clone, Default, Deserialize, PartialEq, Serialize)] @@ -163,6 +165,28 @@ pub struct Recipe { pub package: PackageRecipe, } +impl BuildRecipe { + pub fn new(kind: BuildKind) -> Self { + let mut build = Self::default(); + build.kind = kind; + build + } + + pub fn set_as_remote(&mut self) { + self.kind = BuildKind::Remote; + self.dev_dependencies = Vec::new(); + } +} + +#[derive(Debug, Clone, PartialEq)] +pub struct CookRecipe { + pub name: PackageName, + pub dir: PathBuf, + pub recipe: Recipe, + /// If false, it's listed on install config + pub is_deps: bool, +} + impl Recipe { pub fn new(file: &PathBuf) -> Result { if !file.is_file() { @@ -175,14 +199,6 @@ impl Recipe { Ok(recipe) } } -#[derive(Debug, Clone, PartialEq)] -pub struct CookRecipe { - pub name: PackageName, - pub dir: PathBuf, - pub recipe: Recipe, - /// If false, it's listed on install config - pub is_deps: bool, -} impl CookRecipe { pub fn new(name: PackageName, dir: PathBuf, recipe: Recipe) -> Result { @@ -220,6 +236,7 @@ impl CookRecipe { pub fn new_recursive( names: &[PackageName], recurse_build_deps: bool, + recurse_dev_build_deps: bool, recurse_package_deps: bool, collect_build_deps: bool, collect_package_deps: bool, @@ -238,6 +255,30 @@ impl CookRecipe { let dependencies = Self::new_recursive( &recipe.recipe.build.dependencies, recurse_build_deps, + recurse_dev_build_deps, + recurse_package_deps, + collect_build_deps, + collect_package_deps, + collect_build_deps, + recursion - 1, + ) + .map_err(|mut err| { + err.append_recursion(name); + err + })?; + + for dependency in dependencies { + if !recipes.contains(&dependency) { + recipes.push(dependency); + } + } + } + + if recurse_dev_build_deps { + let dependencies = Self::new_recursive( + &recipe.recipe.build.dev_dependencies, + recurse_build_deps, + recurse_dev_build_deps, recurse_package_deps, collect_build_deps, collect_package_deps, @@ -260,6 +301,7 @@ impl CookRecipe { let dependencies = Self::new_recursive( &recipe.recipe.package.dependencies, recurse_build_deps, + recurse_dev_build_deps, recurse_package_deps, collect_build_deps, collect_package_deps, @@ -288,9 +330,19 @@ impl CookRecipe { pub fn get_build_deps_recursive( names: &[PackageName], + include_dev: bool, mark_is_deps: bool, ) -> Result, PackageError> { - let mut packages = Self::new_recursive(names, true, false, true, false, true, WALK_DEPTH)?; + let mut packages = Self::new_recursive( + names, + true, + include_dev, + false, + true, + false, + true, + WALK_DEPTH, + )?; if mark_is_deps { for package in packages.iter_mut() { @@ -306,8 +358,16 @@ impl CookRecipe { include_names: bool, ) -> Result, PackageError> { // recurse_build_deps == true here as libraries (build deps) can have runtime files (package deps) - let packages = - Self::new_recursive(names, true, true, false, true, include_names, WALK_DEPTH)?; + let packages = Self::new_recursive( + names, + true, + false, + true, + false, + true, + include_names, + WALK_DEPTH, + )?; Ok(packages.into_iter().map(|p| p.name).collect()) } @@ -351,13 +411,10 @@ mod tests { script: None, shallow_clone: None, }), - build: BuildRecipe { - kind: BuildKind::Cargo { - package_path: None, - cargoflags: String::new(), - }, - dependencies: Vec::new(), - }, + build: BuildRecipe::new(BuildKind::Cargo { + package_path: None, + cargoflags: String::new(), + }), package: PackageRecipe::default(), } ); @@ -392,12 +449,9 @@ mod tests { patches: Vec::new(), script: None, }), - build: BuildRecipe { - kind: BuildKind::Custom { - script: "make".to_string() - }, - dependencies: Vec::new(), - }, + build: BuildRecipe::new(BuildKind::Custom { + script: "make".to_string() + }), package: PackageRecipe::default(), } ); @@ -424,10 +478,7 @@ mod tests { recipe, Recipe { source: None, - build: BuildRecipe { - kind: BuildKind::None, - dependencies: Vec::new(), - }, + build: BuildRecipe::new(BuildKind::None), package: PackageRecipe { dependencies: vec![PackageName::new("gcc13").unwrap()], version: None, From 233d159760b4c7fde0e70d6e5accb45afb470483 Mon Sep 17 00:00:00 2001 From: Wildan M Date: Fri, 7 Nov 2025 16:53:34 +0700 Subject: [PATCH 2/4] Print as new lines --- src/cook/cook_build.rs | 2 +- src/cook/pty.rs | 7 +++---- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/cook/cook_build.rs b/src/cook/cook_build.rs index b790062fb..24657a527 100644 --- a/src/cook/cook_build.rs +++ b/src/cook/cook_build.rs @@ -405,7 +405,7 @@ fn build_auto_deps( for dep in &static_deps { if !recipe.package.dependencies.contains(dep) { log_to_pty!( - &logger, + logger, "WARNING: build deps {} is not linked in auto_deps", dep.as_str() ); diff --git a/src/cook/pty.rs b/src/cook/pty.rs index ae1c2aeca..c2aed74cd 100644 --- a/src/cook/pty.rs +++ b/src/cook/pty.rs @@ -20,10 +20,9 @@ macro_rules! log_to_pty { ($logger:expr, $($arg:tt)+) => { if $logger.is_some() { use std::io::Write; - let _ = $logger.as_ref().unwrap().1.try_clone().unwrap().write( - format!($($arg)+) - .as_bytes(), - ); + let logfd = $logger.as_ref().unwrap().1.try_clone().unwrap(); + let _ = logfd.write(format!($($arg)+).as_bytes()); + let _ = logfd.write(b'\n'); } else { eprintln!($($arg)+); } From c3cb1f6a2f891c0af1e1d7f3a4ddeeff7749b518 Mon Sep 17 00:00:00 2001 From: Wildan M Date: Fri, 7 Nov 2025 17:20:26 +0700 Subject: [PATCH 3/4] Filter static to only direct deps --- src/cook/cook_build.rs | 3 ++- src/cook/pty.rs | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/cook/cook_build.rs b/src/cook/cook_build.rs index 24657a527..28e6b4908 100644 --- a/src/cook/cook_build.rs +++ b/src/cook/cook_build.rs @@ -377,7 +377,7 @@ fn build_auto_deps( recipe: &Recipe, target_dir: &Path, stage_dir: &PathBuf, - dep_pkgars: BTreeSet<(PackageName, PathBuf)>, + mut dep_pkgars: BTreeSet<(PackageName, PathBuf)>, logger: &PtyOut, ) -> Result, String> { let auto_deps_path = target_dir.join("auto_deps.toml"); @@ -393,6 +393,7 @@ fn build_auto_deps( wrapper.packages } else { let mut dynamic_deps = auto_deps_from_dynamic_linking(stage_dir, &dep_pkgars, logger); + dep_pkgars.retain(|x| recipe.build.dependencies.contains(&x.0)); let (package_deps, static_deps) = auto_deps_from_static_package_deps(&dep_pkgars, &dynamic_deps).unwrap_or_default(); dynamic_deps.extend(package_deps); diff --git a/src/cook/pty.rs b/src/cook/pty.rs index c2aed74cd..aec8869b0 100644 --- a/src/cook/pty.rs +++ b/src/cook/pty.rs @@ -20,9 +20,9 @@ macro_rules! log_to_pty { ($logger:expr, $($arg:tt)+) => { if $logger.is_some() { use std::io::Write; - let logfd = $logger.as_ref().unwrap().1.try_clone().unwrap(); + let mut logfd = $logger.as_ref().unwrap().1.try_clone().unwrap(); let _ = logfd.write(format!($($arg)+).as_bytes()); - let _ = logfd.write(b'\n'); + let _ = logfd.write(&[b'\n']); } else { eprintln!($($arg)+); } From cc9e04a9559d509f7f2de03bdbe2de733d6bc0fb Mon Sep 17 00:00:00 2001 From: Wildan M Date: Fri, 7 Nov 2025 18:09:35 +0700 Subject: [PATCH 4/4] Apply tidyup and remove warn --- recipes/demos/sdl2-gears/recipe.toml | 9 --------- recipes/tools/cosmic-files/recipe.toml | 1 - src/cook/cook_build.rs | 22 +++------------------- 3 files changed, 3 insertions(+), 29 deletions(-) diff --git a/recipes/demos/sdl2-gears/recipe.toml b/recipes/demos/sdl2-gears/recipe.toml index 7c582e986..bbe89f0ec 100644 --- a/recipes/demos/sdl2-gears/recipe.toml +++ b/recipes/demos/sdl2-gears/recipe.toml @@ -4,16 +4,7 @@ dependencies = [ "sdl2-image", "sdl2-mixer", "sdl2-ttf", - "sdl2", - "liborbital", "llvm18", - "mesa", - "freetype2", - "libjpeg", - "libpng", - "libogg", - "libvorbis", - "zlib" ] script = """ DYNAMIC_INIT diff --git a/recipes/tools/cosmic-files/recipe.toml b/recipes/tools/cosmic-files/recipe.toml index 49e96c33d..f62a4eac3 100644 --- a/recipes/tools/cosmic-files/recipe.toml +++ b/recipes/tools/cosmic-files/recipe.toml @@ -6,7 +6,6 @@ branch = "master" template = "custom" dependencies = [ "gettext", - "libiconv", "libxkbcommon", ] script = """ diff --git a/src/cook/cook_build.rs b/src/cook/cook_build.rs index 28e6b4908..27827a21d 100644 --- a/src/cook/cook_build.rs +++ b/src/cook/cook_build.rs @@ -148,7 +148,7 @@ fn auto_deps_from_dynamic_linking( fn auto_deps_from_static_package_deps( build_dep_pkgars: &BTreeSet<(PackageName, PathBuf)>, dynamic_dep_pkgars: &BTreeSet, -) -> Result<(BTreeSet, Vec), PackageError> { +) -> Result, PackageError> { let static_dep_pkgars: Vec = build_dep_pkgars .iter() .map(|x| x.0.clone()) @@ -156,7 +156,7 @@ fn auto_deps_from_static_package_deps( .collect(); let pkgs = CookRecipe::get_package_deps_recursive(&static_dep_pkgars, false)?; - Ok((pkgs.into_iter().collect(), static_dep_pkgars)) + Ok(pkgs.into_iter().collect()) } pub fn build( @@ -394,26 +394,10 @@ fn build_auto_deps( } else { let mut dynamic_deps = auto_deps_from_dynamic_linking(stage_dir, &dep_pkgars, logger); dep_pkgars.retain(|x| recipe.build.dependencies.contains(&x.0)); - let (package_deps, static_deps) = + let package_deps = auto_deps_from_static_package_deps(&dep_pkgars, &dynamic_deps).unwrap_or_default(); dynamic_deps.extend(package_deps); - // if auto_deps working, all build deps should be linked as auto_deps, otherwise: - // 1. it's weakly linked, which should be mentioned as package deps - // 2. it's not our direct ELF dependencies, which should be removed from build deps - // 3. only needed for build purpose, which should be moved to dev build deps - if dynamic_deps.len() > 0 && static_deps.len() > 0 { - for dep in &static_deps { - if !recipe.package.dependencies.contains(dep) { - log_to_pty!( - logger, - "WARNING: build deps {} is not linked in auto_deps", - dep.as_str() - ); - } - } - } - let wrapper = AutoDeps { packages: dynamic_deps, };