101 lines
3.3 KiB
Rust
101 lines
3.3 KiB
Rust
use core::panic;
|
|
use std::{collections::HashMap, env::args, fs::read_to_string, process::exit};
|
|
|
|
use clap::Parser;
|
|
|
|
mod content_generation;
|
|
mod deser;
|
|
mod parse_deser;
|
|
mod validation;
|
|
|
|
use content_generation::*;
|
|
use deser::*;
|
|
use parse_deser::*;
|
|
|
|
/// ngen is a build file generator for the ninja build system.
|
|
#[derive(Parser)]
|
|
struct Args {
|
|
/// Path to the toml configuration file
|
|
#[arg(short, long, default_value = "ngen.toml")]
|
|
config_file: String,
|
|
|
|
/// Path to generated ninja file
|
|
#[arg(short, long, default_value = "build.ninja")]
|
|
output_file: String,
|
|
|
|
#[arg(long, hide = true)]
|
|
write_compile_commands: Option<String>,
|
|
}
|
|
|
|
fn main() {
|
|
let args = Args::parse();
|
|
|
|
let ngen_toml = read_to_string(&args.config_file)
|
|
.unwrap_or_else(|e| panic!("error reading config file `{}`: {e}", args.config_file));
|
|
let deser_ngen_toml: DeserNgenToml = toml::from_str(&ngen_toml)
|
|
.unwrap_or_else(|e| panic!("error parsing config file `{}`: {e}", args.config_file));
|
|
|
|
let target_option_list: TargetOptionList;
|
|
let deser_target_list: &DeserTargetList;
|
|
match &deser_ngen_toml.targets {
|
|
Some(v) => {
|
|
target_option_list = TargetOptionList::from(v);
|
|
deser_target_list = &v;
|
|
}
|
|
None => panic!("no targets provided, nothing to do. Exiting"),
|
|
};
|
|
|
|
target_option_list
|
|
.check_for_dependency_cycle()
|
|
.unwrap_or_else(|e| panic!("{e}. cannont continue. Exiting"));
|
|
|
|
let inheritance_order = target_option_list
|
|
.get_inheritance_order()
|
|
.unwrap_or_else(|e| panic!("{e}. cannot continue. Exiting"));
|
|
|
|
let mut target_list: TargetList = TargetList(HashMap::new());
|
|
for order in &inheritance_order {
|
|
for name in order.into_iter().rev() {
|
|
let opts = target_option_list.0.get(name as &str).unwrap();
|
|
let deser = deser_target_list.get(name as &str).unwrap();
|
|
|
|
let parent: Option<&Target>;
|
|
if opts.inherit && (name != opts.inherit_from) {
|
|
parent = Some(target_list.0.get(opts.inherit_from as &str).unwrap());
|
|
} else {
|
|
parent = None;
|
|
}
|
|
|
|
target_list.0.insert(name, Target::new(opts, deser, parent));
|
|
}
|
|
}
|
|
|
|
target_list
|
|
.check_if_any_sources_are_provided()
|
|
.unwrap_or_else(|e| panic!("{e}, nothing to do. Exiting"));
|
|
|
|
let config = match &deser_ngen_toml.config {
|
|
Some(v) => Config::from(v),
|
|
None => Config::get_default(),
|
|
};
|
|
|
|
config
|
|
.check_compile_commands_target(&target_list)
|
|
.unwrap_or_else(|e| panic!("{e}"));
|
|
|
|
if let Some(filename) = &args.write_compile_commands {
|
|
let name = config.compile_commands_target;
|
|
let target = target_list.0.get(name).unwrap();
|
|
let content = create_compile_commands_content(name, target, &config)
|
|
.unwrap_or_else(|e| panic!("{e}"));
|
|
write_compile_commands(filename, content.as_bytes()).unwrap_or_else(|e| {
|
|
panic!("could not write compile commands file `{}`: {e}", filename)
|
|
});
|
|
exit(0);
|
|
}
|
|
|
|
let ninja_file_content =
|
|
create_ninja_file_content(&target_list, &config, &args).unwrap_or_else(|e| panic!("{e}"));
|
|
write_ninja_file(&args.output_file, ninja_file_content.as_bytes())
|
|
.unwrap_or_else(|e| panic!("could not write ninja file `{}`: {e}", args.output_file));
|
|
}
|