diff --git a/crates/renderling-build/src/lib.rs b/crates/renderling-build/src/lib.rs index 054be92..53de687 100644 --- a/crates/renderling-build/src/lib.rs +++ b/crates/renderling-build/src/lib.rs @@ -109,10 +109,15 @@ pub struct RenderlingPaths { pub linkage_dir: std::path::PathBuf, } -impl Default for RenderlingPaths { - fn default() -> Self { - let cargo_workspace = - std::path::PathBuf::from(std::env::var("CARGO_WORKSPACE_DIR").unwrap()); +impl RenderlingPaths { + /// Create a new `RenderlingPaths`. + /// + /// If the `CARGO_WORKSPACE_DIR` is _not_ available, this most likely means we're building renderling + /// outside of its own source tree, which means we **don't want to compile shaders or generate linkage**. + /// + /// For this reason we return `Option`. + pub fn new() -> Option { + let cargo_workspace = std::path::PathBuf::from(std::env::var("CARGO_WORKSPACE_DIR").ok()?); let renderling_crate = cargo_workspace.join("crates").join("renderling"); log::debug!("cargo_manifest_dir: {renderling_crate:#?}"); let shader_dir = renderling_crate.join("shaders"); @@ -120,62 +125,61 @@ impl Default for RenderlingPaths { let shader_manifest = shader_dir.join("manifest.json"); let linkage_dir = renderling_crate.join("src").join("linkage"); - Self { + Some(Self { cargo_workspace, renderling_crate, shader_dir, shader_manifest, linkage_dir, - } - } -} -/// Generate linkage (Rust source) files for each shader in the manifest. -pub fn generate_linkage() { - log::trace!("{:#?}", std::env::vars().collect::>()); - let paths = RenderlingPaths::default(); - - assert!( - paths.shader_manifest.is_file(), - "missing file '{}', you must first compile the shaders", - paths.shader_manifest.display() - ); - - if !paths.linkage_dir.is_dir() { - log::info!("creating linkage directory"); - std::fs::create_dir_all(&paths.linkage_dir).unwrap(); + }) } - log::debug!("cwd: {:?}", std::env::current_dir().unwrap()); + /// Generate linkage (Rust source) files for each shader in the manifest. + pub fn generate_linkage(&self) { + log::trace!("{:#?}", std::env::vars().collect::>()); + assert!( + self.shader_manifest.is_file(), + "missing file '{}', you must first compile the shaders", + self.shader_manifest.display() + ); + + if !self.linkage_dir.is_dir() { + log::info!("creating linkage directory"); + std::fs::create_dir_all(&self.linkage_dir).unwrap(); + } + + log::debug!("cwd: {:?}", std::env::current_dir().unwrap()); - let manifest_file = std::fs::File::open(&paths.shader_manifest).unwrap(); - let manifest: Vec = serde_json::from_reader(manifest_file).unwrap(); - let mut set = std::collections::HashSet::new(); - for linkage in manifest.into_iter() { - log::debug!("linkage: {linkage:#?}"); - let fn_name = linkage.fn_name(); + let manifest_file = std::fs::File::open(&self.shader_manifest).unwrap(); + let manifest: Vec = serde_json::from_reader(manifest_file).unwrap(); + let mut set = std::collections::HashSet::new(); + for linkage in manifest.into_iter() { + log::debug!("linkage: {linkage:#?}"); + let fn_name = linkage.fn_name(); - if set.contains(fn_name) { - panic!("Shader name '{fn_name}' is used for two or more shaders, aborting!"); + if set.contains(fn_name) { + panic!("Shader name '{fn_name}' is used for two or more shaders, aborting!"); + } + set.insert(fn_name.to_string()); + + let absolute_source_path = self + .shader_dir + .join(linkage.source_path.file_name().unwrap()); + let wgsl_source_path = linkage.source_path.with_extension("wgsl"); + let absolute_wgsl_source_path = + self.shader_dir.join(wgsl_source_path.file_name().unwrap()); + wgsl(absolute_source_path, absolute_wgsl_source_path); + + let filepath = self.linkage_dir.join(fn_name).with_extension("rs"); + log::info!("generating: {}", linkage.entry_point,); + + let contents = linkage.to_string(); + std::fs::write(&filepath, contents).unwrap(); + std::process::Command::new("rustfmt") + .args([&format!("{}", filepath.display())]) + .output() + .expect("could not format generated code"); } - set.insert(fn_name.to_string()); - - let absolute_source_path = paths - .shader_dir - .join(linkage.source_path.file_name().unwrap()); - let wgsl_source_path = linkage.source_path.with_extension("wgsl"); - let absolute_wgsl_source_path = - paths.shader_dir.join(wgsl_source_path.file_name().unwrap()); - wgsl(absolute_source_path, absolute_wgsl_source_path); - - let filepath = paths.linkage_dir.join(fn_name).with_extension("rs"); - log::info!("generating: {}", linkage.entry_point,); - - let contents = linkage.to_string(); - std::fs::write(&filepath, contents).unwrap(); - std::process::Command::new("rustfmt") - .args([&format!("{}", filepath.display())]) - .output() - .expect("could not format generated code"); + log::info!("...done!") } - log::info!("...done!") } diff --git a/crates/renderling/src/build.rs b/crates/renderling/src/build.rs index f2ae999..88dc47a 100644 --- a/crates/renderling/src/build.rs +++ b/crates/renderling/src/build.rs @@ -2,7 +2,9 @@ fn main() { if std::env::var("CARGO_CFG_TARGET_ARCH").as_deref() != Ok("spirv") { - renderling_build::generate_linkage(); + if let Some(paths) = renderling_build::RenderlingPaths::new() { + paths.generate_linkage(); + } } cfg_aliases::cfg_aliases! { diff --git a/crates/xtask/src/main.rs b/crates/xtask/src/main.rs index be0be3f..7735b02 100644 --- a/crates/xtask/src/main.rs +++ b/crates/xtask/src/main.rs @@ -23,7 +23,7 @@ fn main() { let cli = Cli::parse(); match cli.subcommand { Command::CompileShaders => { - let paths = renderling_build::RenderlingPaths::default(); + let paths = renderling_build::RenderlingPaths::new().unwrap(); log::info!( "Calling `cargo gpu toml {}", @@ -40,7 +40,8 @@ fn main() { } Command::GenerateLinkage => { log::info!("Generating linkage for shaders"); - renderling_build::generate_linkage() + let paths = renderling_build::RenderlingPaths::new().unwrap(); + paths.generate_linkage(); } } }