use std::path::PathBuf;
use crate::{
Tool,
build::{
cargo_builder::CargoBuilder,
config::{Cargo, Custom},
},
run::{
qemu::{RunQemuArgs, resolve_qemu_config_path_in_dir},
uboot::RunUbootArgs,
},
};
pub mod cargo_builder;
pub mod config;
pub mod someboot;
#[derive(Debug, Clone, Default, PartialEq, Eq)]
pub struct CargoQemuOverrideArgs {
pub to_bin: Option<bool>,
pub args: Option<Vec<String>>,
pub success_regex: Option<Vec<String>>,
pub fail_regex: Option<Vec<String>>,
pub shell_prefix: Option<String>,
pub shell_init_cmd: Option<String>,
}
#[derive(Debug, Clone, Default, PartialEq, Eq)]
pub struct CargoQemuAppendArgs {
pub args: Option<Vec<String>>,
pub success_regex: Option<Vec<String>>,
pub fail_regex: Option<Vec<String>>,
}
#[derive(Debug, Clone, Default, PartialEq, Eq)]
pub struct CargoQemuRunnerArgs {
pub qemu_config: Option<PathBuf>,
pub debug: bool,
pub dtb_dump: bool,
pub default_args: CargoQemuOverrideArgs,
pub append_args: CargoQemuAppendArgs,
pub override_args: CargoQemuOverrideArgs,
}
#[derive(Debug, Clone, Default, PartialEq, Eq)]
pub struct CargoUbootRunnerArgs {
pub uboot_config: Option<PathBuf>,
}
pub enum CargoRunnerKind {
Qemu(Box<CargoQemuRunnerArgs>),
Uboot(CargoUbootRunnerArgs),
}
impl Tool {
pub async fn build_with_config(&mut self, config: &config::BuildConfig) -> anyhow::Result<()> {
match &config.system {
config::BuildSystem::Custom(custom) => self.build_custom(custom)?,
config::BuildSystem::Cargo(cargo) => {
self.cargo_build(cargo).await?;
}
}
Ok(())
}
pub async fn build(&mut self, config_path: Option<PathBuf>) -> anyhow::Result<()> {
let build_config = self.prepare_build_config(config_path, false).await?;
println!("Build configuration: {:?}", build_config);
self.build_with_config(&build_config).await
}
pub fn build_custom(&mut self, config: &Custom) -> anyhow::Result<()> {
self.shell_run_cmd(&config.build_cmd)?;
Ok(())
}
pub async fn cargo_build(&mut self, config: &Cargo) -> anyhow::Result<()> {
cargo_builder::CargoBuilder::build_auto(self, config)
.execute()
.await
}
pub async fn cargo_run(
&mut self,
config: &Cargo,
runner: &CargoRunnerKind,
) -> anyhow::Result<()> {
let build_config_path = self.ctx.build_config_path.clone();
let debug = matches!(runner, CargoRunnerKind::Qemu(args) if args.debug);
CargoBuilder::build(self, config, build_config_path)
.debug(debug)
.skip_objcopy(true)
.resolve_artifact_from_json(true)
.execute()
.await?;
match runner {
CargoRunnerKind::Qemu(args) => {
let CargoQemuRunnerArgs {
qemu_config,
dtb_dump,
default_args,
append_args,
override_args,
..
} = args.as_ref();
let package_dir = self.resolve_package_manifest_dir(&config.package)?;
let resolved_qemu_config = resolve_qemu_config_path_in_dir(
&package_dir,
self.ctx.arch,
qemu_config.clone(),
)?;
self.run_qemu_with_layers(
RunQemuArgs {
qemu_config: Some(resolved_qemu_config),
dtb_dump: *dtb_dump,
show_output: true,
},
default_args.clone(),
append_args.clone(),
override_args.clone(),
)
.await?;
}
CargoRunnerKind::Uboot(CargoUbootRunnerArgs { uboot_config }) => {
self.run_uboot(RunUbootArgs {
config: uboot_config.clone(),
show_output: true,
})
.await?;
}
}
Ok(())
}
}