use std::env;
use std::fs::OpenOptions;
#[cfg(not(feature = "hosted"))]
use std::io::Read;
use std::io::Write;
use std::path::PathBuf;
fn out_dir() -> PathBuf { PathBuf::from(env::var_os("OUT_DIR").unwrap()) }
macro_rules! count_enabled_features {
($($feature:literal),*) => {
{
let mut enabled_features = 0;
$(
enabled_features += cfg!(feature = $feature) as u32;
)*
enabled_features
}
}
}
macro_rules! allow_single_feature {
($name:literal, $($feature:literal),*) => {
const _: () = {
const MSG_MULTIPLE: &str = concat!("\nMultiple ", $name, " specified. Only one is allowed.");
const MSG_NONE: &str = concat!("\nNone of the ", $name, " specified. Pick one.");
match count_enabled_features!($($feature),*) {
0 => std::panic!("{}", MSG_NONE),
1 => {}
2.. => std::panic!("{}", MSG_MULTIPLE),
}
};
}
}
macro_rules! allow_single_target_feature {
($($args:tt)+) => {
allow_single_feature!("targets", $($args)+);
}
}
#[cfg(feature = "precursor")] macro_rules! allow_single_gitrev_feature {
($($args:tt)+) => {
allow_single_feature!("gitrevs", $($args)+);
}
}
fn main() {
allow_single_target_feature!(
"precursor",
"hosted",
"renode",
"atsama5d27",
"cramium-soc",
"cramium-fpga"
);
#[cfg(feature = "precursor")]
allow_single_gitrev_feature!("precursor-perflib", "precursor-dvt", "precursor-pvt");
#[cfg(feature = "precursor-perflib")]
let svd_filenames = vec!["precursor/soc-perf.svd"];
#[cfg(feature = "precursor-perflib")]
let generated_filename = "src/generated/precursor_perf.rs";
#[cfg(feature = "renode")]
let svd_filenames = vec!["renode/renode.svd"];
#[cfg(feature = "renode")]
let generated_filename = "src/generated/renode.rs";
#[cfg(feature = "precursor-dvt")]
let svd_filenames = vec!["precursor/soc-dvt.svd"];
#[cfg(feature = "precursor-dvt")]
let generated_filename = "src/generated/precursor_dvt.rs";
#[cfg(feature = "precursor-pvt")]
let svd_filenames = vec!["precursor/soc-pvt.svd"];
#[cfg(feature = "precursor")]
let generated_filename = "src/generated/precursor_pvt.rs";
#[cfg(feature = "atsama5d27")]
let svd_filenames = vec!["atsama5d/ATSAMA5D27.svd"];
#[cfg(feature = "atsama5d27")]
let generated_filename = "src/generated/atsama5d27.rs";
#[cfg(feature = "cramium-soc")]
let svd_filenames = vec!["cramium/core.svd", "cramium/daric.svd"];
#[cfg(feature = "cramium-soc")]
let generated_filename = "src/generated/cramium_soc.rs";
#[cfg(feature = "cramium-fpga")]
let svd_filenames = vec!["cramium/soc.svd", "cramium/core.svd", "cramium/daric.svd"];
#[cfg(feature = "cramium-fpga")]
let generated_filename = "src/generated/cramium_fpga.rs";
#[cfg(not(feature = "hosted"))]
{
let mut svd_files = Vec::new();
for svd in svd_filenames.iter() {
let svd_file_path = std::path::Path::new(&svd);
println!("cargo:rerun-if-changed={}", svd_file_path.canonicalize().unwrap().display());
svd_files.push(std::fs::File::open(svd_file_path).unwrap());
}
let mut dest_vec = vec![];
svd2utra::generate(svd_files, &mut dest_vec).unwrap();
let should_write = if let Ok(mut existing_file) = std::fs::File::open(generated_filename) {
let mut existing_file_contents = vec![];
existing_file
.read_to_end(&mut existing_file_contents)
.expect("couldn't read existing utra generated file");
existing_file_contents != dest_vec
} else {
true
};
if should_write {
let mut dest_file = std::fs::File::create(generated_filename).expect("couldn't open dest file");
dest_file.write_all(&dest_vec).expect("couldn't write contents to utra file");
}
let svd_path = out_dir().join("../../SVD_PATH");
let mut svd_file = OpenOptions::new().create(true).write(true).truncate(true).open(svd_path).unwrap();
for svd in svd_filenames.iter() {
writeln!(svd_file, "utralib/{}", svd).unwrap();
}
}
#[cfg(feature = "hosted")]
{
let svd_path = out_dir().join("../../SVD_PATH");
let mut svd_file = OpenOptions::new().create(true).write(true).truncate(true).open(svd_path).unwrap();
write!(svd_file, "").unwrap(); }
}