use std::env;
use std::fs::OpenOptions;
use std::io::Write;
#[cfg(not(feature = "hosted"))]
use std::io::Read;
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(); }
}