145 lines
3.6 KiB
Rust
145 lines
3.6 KiB
Rust
|
// #![deny(warnings)]
|
||
|
|
||
|
use std::{
|
||
|
fs,
|
||
|
path::{Path, PathBuf},
|
||
|
process::ExitCode,
|
||
|
};
|
||
|
|
||
|
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,
|
||
|
|
||
|
#[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")]
|
||
|
Toolchain {
|
||
|
#[clap(
|
||
|
default_value = "alnyan/yggdrasil-master",
|
||
|
help = "Use a specific toolchain repo branch"
|
||
|
)]
|
||
|
branch: String,
|
||
|
},
|
||
|
#[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
|
||
|
};
|
||
|
let env = env::BuildEnv::new(profile, args.arch, workspace_root);
|
||
|
|
||
|
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),
|
||
|
SubArgs::Toolchain { branch } => build::build_toolchain(env, &branch),
|
||
|
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
|
||
|
}
|
||
|
}
|
||
|
}
|