Skip to content

Commit 1ac317b

Browse files
committed
spirv-builder: move metadata file parsing to invoke_rustc
1 parent 5aad49d commit 1ac317b

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}"
@@ -721,17 +721,13 @@ impl SpirvBuilder {
721721

722722
/// Builds the module
723723
pub fn build(&self) -> Result<CompileResult, SpirvBuilderError> {
724-
let metadata_file = invoke_rustc(self)?;
724+
let out = invoke_rustc(self)?;
725725
if self.build_script.get_dependency_info() {
726-
leaf_deps(&metadata_file, |artifact| {
727-
println!("cargo:rerun-if-changed={artifact}");
728-
})
729-
// Close enough
730-
.map_err(SpirvBuilderError::MetadataFileMissing)?;
726+
for dep in &out.deps {
727+
println!("cargo:rerun-if-changed={dep}");
728+
}
731729
}
732-
let metadata = self.parse_metadata_file(&metadata_file)?;
733-
734-
Ok(metadata)
730+
Ok(out.compile_result)
735731
}
736732

737733
pub(crate) fn parse_metadata_file(
@@ -818,8 +814,12 @@ fn join_checking_for_separators(strings: Vec<impl Borrow<str>>, sep: &str) -> St
818814
strings.join(sep)
819815
}
820816

821-
// Returns path to the metadata json.
822-
fn invoke_rustc(builder: &SpirvBuilder) -> Result<PathBuf, SpirvBuilderError> {
817+
pub struct RustcOutput {
818+
pub compile_result: CompileResult,
819+
pub deps: Vec<RawString>,
820+
}
821+
822+
fn invoke_rustc(builder: &SpirvBuilder) -> Result<RustcOutput, SpirvBuilderError> {
823823
let path_to_crate = builder
824824
.path_to_crate
825825
.as_ref()
@@ -1090,24 +1090,35 @@ fn invoke_rustc(builder: &SpirvBuilder) -> Result<PathBuf, SpirvBuilderError> {
10901090
// that ended up on stdout instead of stderr.
10911091
let stdout = String::from_utf8(build.stdout).unwrap();
10921092
if build.status.success() {
1093-
get_sole_artifact(&stdout).ok_or(SpirvBuilderError::NoArtifactProduced { stdout })
1093+
let metadata_file =
1094+
get_sole_artifact(&stdout).ok_or(SpirvBuilderError::NoArtifactProduced { stdout })?;
1095+
let compile_result = builder.parse_metadata_file(&metadata_file)?;
1096+
let mut deps = Vec::new();
1097+
leaf_deps(&metadata_file, |artifact| {
1098+
deps.push(RawString::from(artifact));
1099+
})
1100+
.map_err(SpirvBuilderError::MetadataFileMissing)?;
1101+
Ok(RustcOutput {
1102+
compile_result,
1103+
deps,
1104+
})
10941105
} else {
10951106
Err(SpirvBuilderError::BuildFailed)
10961107
}
10971108
}
10981109

1099-
#[derive(Deserialize)]
1100-
struct RustcOutput {
1101-
reason: String,
1102-
filenames: Option<Vec<String>>,
1103-
}
1104-
11051110
const ARTIFACT_SUFFIX: &str = ".spv.json";
11061111

11071112
fn get_sole_artifact(out: &str) -> Option<PathBuf> {
1113+
#[derive(Deserialize)]
1114+
struct RustcLine {
1115+
reason: String,
1116+
filenames: Option<Vec<String>>,
1117+
}
1118+
11081119
let mut last_compiler_artifact = None;
11091120
for line in out.lines() {
1110-
let Ok(msg) = serde_json::from_str::<RustcOutput>(line) else {
1121+
let Ok(msg) = serde_json::from_str::<RustcLine>(line) else {
11111122
// Pass through invalid lines
11121123
println!("{line}");
11131124
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,
@@ -124,10 +124,9 @@ impl SpirvWatcher {
124124
}
125125

126126
let result = (|| {
127-
let metadata_file = crate::invoke_rustc(&self.builder)?;
128-
let result = self.builder.parse_metadata_file(&metadata_file)?;
129-
self.watch_leaf_deps(&metadata_file)?;
130-
Ok(result)
127+
let out = crate::invoke_rustc(&self.builder)?;
128+
self.watch_leaf_deps(out.deps.iter().map(|d| d.as_ref()));
129+
Ok(out.compile_result)
131130
})();
132131
match result {
133132
Ok(result) => {
@@ -155,16 +154,15 @@ impl SpirvWatcher {
155154
}
156155
}
157156

158-
fn watch_leaf_deps(&mut self, watch_path: &Path) -> Result<(), SpirvBuilderError> {
159-
leaf_deps(watch_path, |artifact| {
160-
let path = artifact.to_path().unwrap();
157+
fn watch_leaf_deps<'a>(&mut self, deps: impl Iterator<Item = &'a RawStr>) {
158+
for dep in deps {
159+
let path = dep.to_path().unwrap();
161160
if self.watched_paths.insert(path.to_owned())
162161
&& let Err(err) = self.watcher.watch(path, RecursiveMode::NonRecursive)
163162
{
164-
log::error!("files of cargo dependencies are not valid: {err}");
163+
log::error!("failed to watch `{}`: {err}", path.display());
165164
}
166-
})
167-
.map_err(SpirvBuilderError::MetadataFileMissing)
165+
}
168166
}
169167
}
170168

0 commit comments

Comments
 (0)