2024-04-12 12:24:00 +03:00
|
|
|
#![deny(warnings)]
|
2024-03-12 18:17:47 +02:00
|
|
|
|
2024-03-12 19:39:04 +02:00
|
|
|
use std::{fs, path::PathBuf, process::ExitCode};
|
2024-03-12 18:17:47 +02:00
|
|
|
|
|
|
|
use build::CheckAction;
|
|
|
|
use clap::{Parser, Subcommand};
|
|
|
|
use env::{Arch, Profile};
|
|
|
|
use error::Error;
|
|
|
|
|
|
|
|
#[macro_use]
|
|
|
|
pub mod util;
|
|
|
|
|
|
|
|
pub mod build;
|
|
|
|
pub mod check;
|
|
|
|
pub mod env;
|
|
|
|
pub mod error;
|
|
|
|
pub mod qemu;
|
|
|
|
|
|
|
|
#[derive(Parser)]
|
|
|
|
struct Args {
|
|
|
|
#[clap(long, env, help = "Use --release profile for built components")]
|
|
|
|
release: bool,
|
|
|
|
#[clap(
|
|
|
|
short,
|
|
|
|
long,
|
|
|
|
env,
|
|
|
|
default_value_t,
|
|
|
|
value_enum,
|
|
|
|
help = "Target architecture"
|
|
|
|
)]
|
|
|
|
arch: Arch,
|
|
|
|
#[clap(
|
|
|
|
short,
|
|
|
|
long,
|
|
|
|
help = "Do a clean userspace rebuild (e.g. toolchain has changed)"
|
|
|
|
)]
|
|
|
|
clean_userspace: bool,
|
2024-03-20 21:21:39 +02:00
|
|
|
#[clap(short, long, help = "Be verbose where possible")]
|
|
|
|
verbose: bool,
|
2024-03-12 18:17:47 +02:00
|
|
|
|
2024-03-12 19:39:04 +02:00
|
|
|
#[clap(
|
|
|
|
short = 'C',
|
|
|
|
long,
|
|
|
|
default_value = "xtask.toml",
|
|
|
|
help = "Configuration path"
|
|
|
|
)]
|
|
|
|
config_path: PathBuf,
|
|
|
|
|
2024-03-12 18:17:47 +02:00
|
|
|
#[clap(subcommand)]
|
|
|
|
action: Option<SubArgs>,
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Default, Subcommand)]
|
|
|
|
enum SubArgs {
|
|
|
|
#[default]
|
|
|
|
#[clap(about = "Build the OS")]
|
|
|
|
Build,
|
|
|
|
#[clap(about = "Run `cargo check` on components")]
|
|
|
|
Check,
|
|
|
|
#[clap(about = "Run `cargo clippy` on components")]
|
|
|
|
Clippy,
|
|
|
|
#[clap(about = "Run `cargo test` on components")]
|
|
|
|
Test,
|
|
|
|
#[clap(about = "Clean all build artifacts")]
|
|
|
|
Clean {
|
|
|
|
#[clap(short, long, help = "Clean toolchain as well")]
|
|
|
|
toolchain: bool,
|
|
|
|
},
|
|
|
|
|
|
|
|
// #[clap(about = "Print `git status` for the components", alias = "gst")]
|
|
|
|
// GitStatus,
|
|
|
|
#[clap(about = "Run the OS image in QEMU")]
|
|
|
|
Qemu {
|
|
|
|
#[clap(
|
|
|
|
short,
|
|
|
|
long,
|
|
|
|
env,
|
|
|
|
help = "Override the default QEMU binary for the target"
|
|
|
|
)]
|
|
|
|
qemu: Option<PathBuf>,
|
|
|
|
#[clap(help = "Extra arguments for QEMU")]
|
|
|
|
extra_args: Vec<String>,
|
|
|
|
},
|
|
|
|
|
|
|
|
#[clap(about = "Build the Yggdrasil OS Rust toolchain")]
|
2024-03-12 19:39:04 +02:00
|
|
|
Toolchain { branch: Option<String> },
|
2024-03-12 18:17:47 +02:00
|
|
|
#[clap(about = "Print the host triple")]
|
|
|
|
HostTriple,
|
|
|
|
}
|
|
|
|
|
|
|
|
fn run(args: Args) -> Result<(), Error> {
|
|
|
|
let action = args.action.unwrap_or_default();
|
|
|
|
|
|
|
|
let workspace_root = std::env::current_dir()?;
|
|
|
|
let profile = if args.release {
|
|
|
|
Profile::Release
|
|
|
|
} else {
|
|
|
|
Profile::Debug
|
|
|
|
};
|
2024-04-01 17:23:12 +03:00
|
|
|
let config = toml::from_str(&fs::read_to_string(&args.config_path)?)
|
|
|
|
.map_err(|e| Error::TomlParseError(args.config_path.clone(), e))?;
|
2024-03-20 21:21:39 +02:00
|
|
|
let env = env::BuildEnv::new(config, args.verbose, profile, args.arch, workspace_root);
|
2024-03-12 18:17:47 +02:00
|
|
|
|
|
|
|
if args.clean_userspace && !matches!(&action, SubArgs::Clean { .. }) {
|
|
|
|
build::clean_userspace(&env)?;
|
|
|
|
}
|
|
|
|
|
|
|
|
match action {
|
|
|
|
SubArgs::Build => build::build_all(env).map(|_| ()),
|
|
|
|
SubArgs::Check => build::check_all(env, CheckAction::Check),
|
|
|
|
SubArgs::Clippy => build::check_all(env, CheckAction::Clippy),
|
|
|
|
SubArgs::Test => build::test_all(env),
|
|
|
|
SubArgs::Clean { toolchain } => build::clean_all(&env, toolchain),
|
|
|
|
// SubArgs::GitStatus => util::git_status_all(&env),
|
|
|
|
SubArgs::Qemu { qemu, extra_args } => qemu::run(env, qemu, extra_args),
|
2024-03-12 19:39:04 +02:00
|
|
|
SubArgs::Toolchain { branch } => {
|
|
|
|
let branch = branch.as_ref().unwrap_or(&env.config.toolchain.branch);
|
|
|
|
build::build_toolchain(&env, branch)
|
|
|
|
}
|
2024-03-12 18:17:47 +02:00
|
|
|
SubArgs::HostTriple => {
|
|
|
|
println!("{}", env.host_triple);
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn main() -> ExitCode {
|
|
|
|
env_logger::builder()
|
|
|
|
.filter_level(log::LevelFilter::Info)
|
|
|
|
.parse_default_env()
|
|
|
|
.init();
|
|
|
|
|
|
|
|
let args = Args::parse();
|
|
|
|
|
|
|
|
match run(args) {
|
|
|
|
Ok(()) => ExitCode::SUCCESS,
|
|
|
|
Err(Error::MissingTools(list)) => {
|
|
|
|
eprintln!("Missing some required tools:");
|
|
|
|
for (tool, guide) in list {
|
|
|
|
eprintln!(" * {}: {}", tool, guide);
|
|
|
|
}
|
|
|
|
ExitCode::FAILURE
|
|
|
|
}
|
|
|
|
Err(err) => {
|
|
|
|
eprintln!("Error: {}", err);
|
|
|
|
ExitCode::FAILURE
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|