use glob::glob; use std::path::{Path, PathBuf}; use std::process::Command; #[cfg(target_os = "macos")] const GLSL_COMPILER_PATH: &str = "/Users/hahaliu/VulkanSDK/1.3.261.1/macOS/bin/glslc"; #[cfg(target_os = "windows")] const GLSL_COMPILER_PATH: &str = "C:/VulkanSDK/1.3.261.1/Bin/glslc.exe"; const SHADER_SRC_DIRS: [&str; 2] = ["src/shaders", "examples/shaders"]; fn shader_paths_in_dir>(dir: &P) -> Vec { let mut shader_paths = vec![]; for suffix in ["*.vert", "*.frag", "*.comp"] { for entry in glob(dir.as_ref().join("**").join(suffix).to_str().unwrap()) .expect("Failed to read glob pattern") { shader_paths.push(entry.unwrap()); } } shader_paths } fn compile_shader>(compiler: P, shader: P) { println!("Compiling shader: {}", shader.as_ref().display()); Command::new(compiler.as_ref()) .args([ shader.as_ref().to_str().unwrap(), "-o", &(shader.as_ref().to_str().unwrap().to_owned() + ".spv"), ]) .output() .unwrap_or_else(|_| panic!("failed at compile shader: {}", shader.as_ref().display())); println!( "Compiling shader output: {}", shader.as_ref().to_str().unwrap().to_owned() + ".spv" ); } fn compile_shaders() { let compiler = Path::new(&GLSL_COMPILER_PATH); assert!( compiler.exists(), "glsl compiler path {GLSL_COMPILER_PATH} not exists, please check" ); SHADER_SRC_DIRS .iter() .for_each(|p| println!("cargo:rerun-if-changed={p}")); let shader_paths = SHADER_SRC_DIRS .iter() .map(|p| shader_paths_in_dir(&std::env::current_dir().unwrap().join(p))) .collect::>() .concat(); shader_paths .iter() .for_each(|s| compile_shader(compiler, s)); } fn main() { println!("Runing build scripts"); compile_shaders(); }