#![deny(warnings)]
use glob::glob;
use std::env;
use std::path::PathBuf;
use std::process::{Child, Command};
fn main() {
let mut runners = Vec::new();
println!("cargo:rerun-if-env-changed=SHADERC");
let shaderc = match env::var("SHADERC") {
Ok(s) => Some(s),
Err(env::VarError::NotPresent) => None,
Err(e) => panic!("failed to read env var SHADERC: {e}"),
};
let mut pat = env::var("CARGO_MANIFEST_DIR").unwrap();
pat.push_str("/**/*.vert");
walk(&pat, &shaderc, &mut runners);
pat.replace_range((pat.len() - 4).., "frag");
walk(&pat, &shaderc, &mut runners);
for mut r in runners {
let status = r.wait().unwrap();
if !status.success() {
panic!("Shader compilation failed (exit code {:?})", status.code());
}
}
}
fn walk(pat: &str, shaderc: &Option<String>, runners: &mut Vec<Child>) {
for path in glob(pat).unwrap().filter_map(Result::ok) {
println!("cargo:rerun-if-changed={}", path.display());
let mut path_spv = path.clone().into_os_string();
path_spv.push(".spv");
let path_spv = PathBuf::from(path_spv);
let gen = match path_spv.metadata() {
Ok(meta) => {
let orig_meta = path.metadata().unwrap();
orig_meta.modified().unwrap() > meta.modified().unwrap()
}
Err(_) => true,
};
if gen {
if let Some(bin) = shaderc.as_ref() {
let mut cmd = Command::new(bin);
cmd.arg(&path).arg("-o").arg(&path_spv);
eprintln!("Launching: {cmd:?}");
runners.push(cmd.spawn().expect("shader compiler failed to start"));
} else {
eprintln!(
"cargo:warning=Shader compilation required: {}",
path.display()
);
eprintln!("cargo:warning=No shader found. If you have a shader compiler such as glslc installed, try setting SHADERC=glslc");
}
}
}
}