exp: cross #4

This commit is contained in:
2025-12-21 22:07:34 +01:00
parent 0d4ae565dd
commit 75751ad301
2 changed files with 42 additions and 16 deletions

View File

@@ -6,11 +6,18 @@ use crate::context;
use std::error::Error;
use std::path::{Path, PathBuf};
#[derive(PartialEq)]
pub enum BuildMode {
Sbuild,
Local,
}
pub fn build_binary_package(
arch: Option<&str>,
series: Option<&str>,
cwd: Option<&Path>,
cross: bool,
mode: Option<BuildMode>,
) -> Result<(), Box<dyn Error>> {
let cwd = cwd.unwrap_or_else(|| Path::new("."));
@@ -26,14 +33,29 @@ pub fn build_binary_package(
let current_arch = crate::get_current_arch();
let arch = arch.unwrap_or(&current_arch);
// Make sure we select a specific mode, either using user-requested
// or by using default for user-supplied parameters
let mode = if let Some(m) = mode {
m
} else {
// For cross-compilation, we use local with an ephemeral context
// created by the cross-compilation handler (see below)
if cross {
BuildMode::Local
} else {
// By default, we use sbuild
BuildMode::Sbuild
}
};
// Specific case: native cross-compilation, we don't allow that
// instead this wraps to an automatic unshare chroot
// using an ephemeral context
if cross {
if cross && mode == BuildMode::Local {
cross::setup_native_context(series)?;
}
// Prepare Environment
// Prepare build directory
let ctx = context::current();
let build_root = ctx.create_temp_dir()?;
@@ -45,18 +67,13 @@ pub fn build_binary_package(
.ok_or("Cannot find parent directory name")?;
let build_root = format!("{}/{}", build_root, parent_dir_name.to_str().unwrap());
// Run sbuild
if cross {
local::build(&package, &version, arch, series, &build_root, cross)?;
} else {
sbuild::build(&package, &version, arch, series, &build_root, cross)?;
}
// Run the build using target build mode
match mode {
BuildMode::Local => local::build(&package, &version, arch, series, &build_root, cross)?,
BuildMode::Sbuild => sbuild::build(&package, &version, arch, series, &build_root, cross)?,
};
// Retrieve artifacts
// Always retrieve to the directory containing the .dsc file
println!("Retrieving artifacts to {}...", parent_dir.display());
// Only retrieve .deb files
// Retrieve produced .deb files
let remote_files = ctx.list_files(Path::new(&build_root))?;
for remote_file in remote_files {
if remote_file.extension().is_some_and(|ext| ext == "deb") {
@@ -66,7 +83,7 @@ pub fn build_binary_package(
}
}
if cross {
if cross && mode == BuildMode::Local {
cross::clean_native_context()?;
}

View File

@@ -55,7 +55,10 @@ fn main() {
.about("Build the binary package")
.arg(arg!(-s --series <series> "Target distribution series").required(false))
.arg(arg!(-a --arch <arch> "Target architecture").required(false))
.arg(arg!(--cross "Cross-compile for target architecture (instead of using qemu-binfmt)").required(false)),
.arg(arg!(--cross "Cross-compile for target architecture (instead of qemu-binfmt)")
.long_help("Cross-compile for target architecture (instead of using qemu-binfmt)\nNote that most packages cannot be cross-compiled").required(false))
.arg(arg!(--mode "Change build mode [sbuild, local]").required(false)
.long_help("Change build mode [sbuild, local]\nDefault will chose depending on other parameters, don't provide if unsure")),
)
.subcommand(
Command::new("context")
@@ -148,9 +151,15 @@ fn main() {
let series = sub_matches.get_one::<String>("series").map(|s| s.as_str());
let arch = sub_matches.get_one::<String>("arch").map(|s| s.as_str());
let cross = sub_matches.get_one::<bool>("cross").unwrap_or(&false);
let mode = sub_matches.get_one::<String>("mode").map(|s| s.as_str());
let mode = match mode {
Some("sbuild") => Some(pkh::deb::BuildMode::Sbuild),
Some("local") => Some(pkh::deb::BuildMode::Local),
_ => None,
};
if let Err(e) =
pkh::deb::build_binary_package(arch, series, Some(cwd.as_path()), *cross)
pkh::deb::build_binary_package(arch, series, Some(cwd.as_path()), *cross, mode)
{
error!("{}", e);
std::process::exit(1);