mirror of
https://github.com/EmbarkStudios/rust-gpu.git
synced 2025-02-16 17:04:16 +00:00
Move to a builder struct for spirv-builder (#59)
This allows the print_metadata option
This commit is contained in:
parent
377bf070f0
commit
d3af0552d3
@ -1,8 +1,8 @@
|
|||||||
use spirv_builder::build_spirv;
|
use spirv_builder::SpirvBuilder;
|
||||||
use std::error::Error;
|
use std::error::Error;
|
||||||
|
|
||||||
fn main() -> Result<(), Box<dyn Error>> {
|
fn main() -> Result<(), Box<dyn Error>> {
|
||||||
// This will set the env var `example-shader.spv` to a spir-v file that can be include!()'d
|
// This will set the env var `example-shader.spv` to a spir-v file that can be include!()'d
|
||||||
build_spirv("../example-shader")?;
|
SpirvBuilder::new("../example-shader").build()?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -24,12 +24,35 @@ impl fmt::Display for SpirvBuilderError {
|
|||||||
|
|
||||||
impl Error for SpirvBuilderError {}
|
impl Error for SpirvBuilderError {}
|
||||||
|
|
||||||
pub fn build_spirv(path_to_crate: impl AsRef<Path>) -> Result<(), SpirvBuilderError> {
|
pub struct SpirvBuilder {
|
||||||
let spirv_module = invoke_rustc(path_to_crate.as_ref())?;
|
path_to_crate: PathBuf,
|
||||||
let spirv_path: &Path = spirv_module.as_ref();
|
print_metadata: bool,
|
||||||
let env_var = spirv_path.file_name().unwrap().to_str().unwrap();
|
}
|
||||||
println!("cargo:rustc-env={}={}", env_var, spirv_module);
|
impl SpirvBuilder {
|
||||||
Ok(())
|
pub fn new(path_to_crate: impl AsRef<Path>) -> Self {
|
||||||
|
Self {
|
||||||
|
path_to_crate: path_to_crate.as_ref().to_owned(),
|
||||||
|
print_metadata: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Whether to print build.rs cargo metadata (e.g. cargo:rustc-env=var=val). Defaults to true.
|
||||||
|
pub fn print_metadata(&mut self, v: bool) -> &mut Self {
|
||||||
|
self.print_metadata = v;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Builds the module. Returns the path to the built spir-v file. If print_metadata is true,
|
||||||
|
/// you usually don't have to inspect the path, as the environment variable will already be
|
||||||
|
/// set.
|
||||||
|
pub fn build(self) -> Result<PathBuf, SpirvBuilderError> {
|
||||||
|
let spirv_module = invoke_rustc(self.path_to_crate.as_ref(), self.print_metadata)?;
|
||||||
|
let env_var = spirv_module.file_name().unwrap().to_str().unwrap();
|
||||||
|
if self.print_metadata {
|
||||||
|
println!("cargo:rustc-env={}={}", env_var, spirv_module.display());
|
||||||
|
}
|
||||||
|
Ok(spirv_module)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://github.com/rust-lang/cargo/blob/1857880b5124580c4aeb4e8bc5f1198f491d61b1/src/cargo/util/paths.rs#L29-L52
|
// https://github.com/rust-lang/cargo/blob/1857880b5124580c4aeb4e8bc5f1198f491d61b1/src/cargo/util/paths.rs#L29-L52
|
||||||
@ -64,7 +87,7 @@ fn find_rustc_codegen_spirv() -> PathBuf {
|
|||||||
panic!("Could not find {} in library path", filename);
|
panic!("Could not find {} in library path", filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn invoke_rustc(path_to_crate: &Path) -> Result<String, SpirvBuilderError> {
|
fn invoke_rustc(path_to_crate: &Path, print_metadata: bool) -> Result<PathBuf, SpirvBuilderError> {
|
||||||
// Okay, this is a little bonkers: in a normal world, we'd have the user clone
|
// Okay, this is a little bonkers: in a normal world, we'd have the user clone
|
||||||
// rustc_codegen_spirv and pass in the path to it, and then we'd invoke cargo to build it, grab
|
// rustc_codegen_spirv and pass in the path to it, and then we'd invoke cargo to build it, grab
|
||||||
// the resulting .so, and pass it into -Z codegen-backend. But that's really gross: the user
|
// the resulting .so, and pass it into -Z codegen-backend. But that's really gross: the user
|
||||||
@ -93,7 +116,9 @@ fn invoke_rustc(path_to_crate: &Path) -> Result<String, SpirvBuilderError> {
|
|||||||
if build.status.success() {
|
if build.status.success() {
|
||||||
let stdout = String::from_utf8(build.stdout).unwrap();
|
let stdout = String::from_utf8(build.stdout).unwrap();
|
||||||
let artifact = get_last_artifact(&stdout);
|
let artifact = get_last_artifact(&stdout);
|
||||||
print_deps_of(&artifact);
|
if print_metadata {
|
||||||
|
print_deps_of(&artifact);
|
||||||
|
}
|
||||||
Ok(artifact)
|
Ok(artifact)
|
||||||
} else {
|
} else {
|
||||||
Err(SpirvBuilderError::BuildFailed)
|
Err(SpirvBuilderError::BuildFailed)
|
||||||
@ -106,7 +131,7 @@ struct RustcOutput {
|
|||||||
filenames: Option<Vec<String>>,
|
filenames: Option<Vec<String>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_last_artifact(out: &str) -> String {
|
fn get_last_artifact(out: &str) -> PathBuf {
|
||||||
let last = out
|
let last = out
|
||||||
.lines()
|
.lines()
|
||||||
.filter_map(|line| match serde_json::from_str::<RustcOutput>(line) {
|
.filter_map(|line| match serde_json::from_str::<RustcOutput>(line) {
|
||||||
@ -128,11 +153,11 @@ fn get_last_artifact(out: &str) -> String {
|
|||||||
.filter(|v| v.ends_with(".spv"));
|
.filter(|v| v.ends_with(".spv"));
|
||||||
let filename = filenames.next().expect("Crate had no .spv artifacts");
|
let filename = filenames.next().expect("Crate had no .spv artifacts");
|
||||||
assert_eq!(filenames.next(), None, "Crate had multiple .spv artifacts");
|
assert_eq!(filenames.next(), None, "Crate had multiple .spv artifacts");
|
||||||
filename
|
filename.into()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn print_deps_of(artifact: &str) {
|
fn print_deps_of(artifact: &Path) {
|
||||||
let deps_file = Path::new(artifact).with_extension("d");
|
let deps_file = artifact.with_extension("d");
|
||||||
let mut deps_map = HashMap::new();
|
let mut deps_map = HashMap::new();
|
||||||
depfile::read_deps_file(&deps_file, |item, deps| {
|
depfile::read_deps_file(&deps_file, |item, deps| {
|
||||||
deps_map.insert(item, deps);
|
deps_map.insert(item, deps);
|
||||||
@ -149,5 +174,5 @@ fn print_deps_of(artifact: &str) {
|
|||||||
None => println!("cargo:rerun-if-changed={}", artifact),
|
None => println!("cargo:rerun-if-changed={}", artifact),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
recurse(&deps_map, artifact.into());
|
recurse(&deps_map, artifact.to_str().unwrap().into());
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user