Skip to content

Commit 1107a11

Browse files
committed
spirv-builder: move metadata file parsing to invoke_rustc
1 parent eb79ff7 commit 1107a11

File tree

2 files changed

+42
-33
lines changed

2 files changed

+42
-33
lines changed

crates/spirv-builder/src/lib.rs

Lines changed: 32 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -117,9 +117,9 @@ pub enum SpirvBuilderError {
117117
"`multimodule: true` build cannot be used together with `build_script.env_shader_spv_path: true`"
118118
)]
119119
MultiModuleWithEnvShaderSpvPath,
120-
#[error("multi-module metadata file missing")]
120+
#[error("some metadata file is missing")]
121121
MetadataFileMissing(#[from] std::io::Error),
122-
#[error("unable to parse multi-module metadata file")]
122+
#[error("unable to parse some metadata file")]
123123
MetadataFileMalformed(#[from] serde_json::Error),
124124
#[error(
125125
"`{ARTIFACT_SUFFIX}` artifact not found in (supposedly successful) build output.\n--- build output ---\n{stdout}"
@@ -739,17 +739,13 @@ impl SpirvBuilder {
739739

740740
/// Builds the module
741741
pub fn build(&self) -> Result<CompileResult, SpirvBuilderError> {
742-
let metadata_file = invoke_rustc(self)?;
742+
let out = invoke_rustc(self)?;
743743
if self.build_script.get_dependency_info() {
744-
leaf_deps(&metadata_file, |artifact| {
745-
println!("cargo:rerun-if-changed={artifact}");
746-
})
747-
// Close enough
748-
.map_err(SpirvBuilderError::MetadataFileMissing)?;
744+
for dep in &out.deps {
745+
println!("cargo:rerun-if-changed={dep}");
746+
}
749747
}
750-
let metadata = self.parse_metadata_file(&metadata_file)?;
751-
752-
Ok(metadata)
748+
Ok(out.compile_result)
753749
}
754750

755751
pub(crate) fn parse_metadata_file(
@@ -836,8 +832,12 @@ fn join_checking_for_separators(strings: Vec<impl Borrow<str>>, sep: &str) -> St
836832
strings.join(sep)
837833
}
838834

839-
// Returns path to the metadata json.
840-
fn invoke_rustc(builder: &SpirvBuilder) -> Result<PathBuf, SpirvBuilderError> {
835+
pub struct RustcOutput {
836+
pub compile_result: CompileResult,
837+
pub deps: Vec<RawString>,
838+
}
839+
840+
fn invoke_rustc(builder: &SpirvBuilder) -> Result<RustcOutput, SpirvBuilderError> {
841841
let path_to_crate = builder
842842
.path_to_crate
843843
.as_ref()
@@ -1108,24 +1108,35 @@ fn invoke_rustc(builder: &SpirvBuilder) -> Result<PathBuf, SpirvBuilderError> {
11081108
// that ended up on stdout instead of stderr.
11091109
let stdout = String::from_utf8(build.stdout).unwrap();
11101110
if build.status.success() {
1111-
get_sole_artifact(&stdout).ok_or(SpirvBuilderError::NoArtifactProduced { stdout })
1111+
let metadata_file =
1112+
get_sole_artifact(&stdout).ok_or(SpirvBuilderError::NoArtifactProduced { stdout })?;
1113+
let compile_result = builder.parse_metadata_file(&metadata_file)?;
1114+
let mut deps = Vec::new();
1115+
leaf_deps(&metadata_file, |artifact| {
1116+
deps.push(RawString::from(artifact));
1117+
})
1118+
.map_err(SpirvBuilderError::MetadataFileMissing)?;
1119+
Ok(RustcOutput {
1120+
compile_result,
1121+
deps,
1122+
})
11121123
} else {
11131124
Err(SpirvBuilderError::BuildFailed)
11141125
}
11151126
}
11161127

1117-
#[derive(Deserialize)]
1118-
struct RustcOutput {
1119-
reason: String,
1120-
filenames: Option<Vec<String>>,
1121-
}
1122-
11231128
const ARTIFACT_SUFFIX: &str = ".spv.json";
11241129

11251130
fn get_sole_artifact(out: &str) -> Option<PathBuf> {
1131+
#[derive(Deserialize)]
1132+
struct RustcLine {
1133+
reason: String,
1134+
filenames: Option<Vec<String>>,
1135+
}
1136+
11261137
let mut last_compiler_artifact = None;
11271138
for line in out.lines() {
1128-
let Ok(msg) = serde_json::from_str::<RustcOutput>(line) else {
1139+
let Ok(msg) = serde_json::from_str::<RustcLine>(line) else {
11291140
// Pass through invalid lines
11301141
println!("{line}");
11311142
continue;

crates/spirv-builder/src/watch.rs

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
use crate::{SpirvBuilder, SpirvBuilderError, leaf_deps};
1+
use crate::{SpirvBuilder, SpirvBuilderError};
22
use notify::{Event, RecommendedWatcher, RecursiveMode, Watcher};
3+
use raw_string::RawStr;
34
use rustc_codegen_spirv_types::CompileResult;
4-
use std::path::Path;
55
use std::sync::mpsc::TryRecvError;
66
use std::{
77
collections::HashSet,
@@ -121,10 +121,9 @@ impl SpirvWatcher {
121121
}
122122

123123
let result = (|| {
124-
let metadata_file = crate::invoke_rustc(&self.builder)?;
125-
let result = self.builder.parse_metadata_file(&metadata_file)?;
126-
self.watch_leaf_deps(&metadata_file)?;
127-
Ok(result)
124+
let out = crate::invoke_rustc(&self.builder)?;
125+
self.watch_leaf_deps(out.deps.iter().map(|d| d.as_ref()));
126+
Ok(out.compile_result)
128127
})();
129128
match result {
130129
Ok(result) => {
@@ -152,16 +151,15 @@ impl SpirvWatcher {
152151
}
153152
}
154153

155-
fn watch_leaf_deps(&mut self, watch_path: &Path) -> Result<(), SpirvBuilderError> {
156-
leaf_deps(watch_path, |artifact| {
157-
let path = artifact.to_path().unwrap();
154+
fn watch_leaf_deps<'a>(&mut self, deps: impl Iterator<Item = &'a RawStr>) {
155+
for dep in deps {
156+
let path = dep.to_path().unwrap();
158157
if self.watched_paths.insert(path.to_owned())
159158
&& let Err(err) = self.watcher.watch(path, RecursiveMode::NonRecursive)
160159
{
161-
log::error!("files of cargo dependencies are not valid: {err}");
160+
log::error!("failed to watch `{}`: {err}", path.display());
162161
}
163-
})
164-
.map_err(SpirvBuilderError::MetadataFileMissing)
162+
}
165163
}
166164
}
167165

0 commit comments

Comments
 (0)