From ca3b52ef7663ec9945d7d76530e7dc679d31d47a Mon Sep 17 00:00:00 2001 From: firestar99 Date: Mon, 10 Aug 2026 15:37:33 +0200 Subject: [PATCH 1/2] new build dir compiletest: cleanup dep building --- tests/compiletests/src/main.rs | 132 +++++++++++++-------------------- 1 file changed, 52 insertions(+), 80 deletions(-) diff --git a/tests/compiletests/src/main.rs b/tests/compiletests/src/main.rs index 23407eb9e51..e290aa4ed51 100644 --- a/tests/compiletests/src/main.rs +++ b/tests/compiletests/src/main.rs @@ -101,7 +101,7 @@ impl Runner { /// RUSTFLAGS passed to all test files. fn test_rustc_flags( codegen_backend_path: &Path, - deps: &TestDeps, + deps: &[TestDep], indirect_deps_dirs: &[&Path], ) -> String { [ @@ -111,17 +111,7 @@ impl Runner { .map(|dir| format!("-L dependency={}", dir.display())) .fold(String::new(), |a, b| b + " " + &a), "--edition 2021", - &*format!("--extern noprelude:core={}", deps.core.display()), - &*format!( - "--extern noprelude:compiler_builtins={}", - deps.compiler_builtins.display() - ), - &*format!( - "--extern spirv_std_macros={}", - deps.spirv_std_macros.display() - ), - &*format!("--extern spirv_std={}", deps.spirv_std.display()), - &*format!("--extern glam={}", deps.glam.display()), + &*deps.iter().map(TestDep::to_rustc_param).join(" "), "--crate-type dylib", "-Zunstable-options", "-Zcrate-attr=no_std", @@ -199,7 +189,7 @@ impl Runner { } /// Runs the processes needed to build `spirv-std` & other deps. - fn build_deps(&self, target: &SpirvTarget, target_spec: &TargetSpec) -> TestDeps { + fn build_deps(&self, target: &SpirvTarget, target_spec: &TargetSpec) -> Vec { // Build compiletests-deps-helper let mut cmd = std::process::Command::new("cargo"); cmd.args([ @@ -219,44 +209,23 @@ impl Runner { .and_then(map_status_to_result) .unwrap(); - let compiler_builtins = self.find_lib("compiler_builtins", DepKind::SpirvLib, target); - let core = self.find_lib("core", DepKind::SpirvLib, target); - let spirv_std = self.find_lib("spirv_std", DepKind::SpirvLib, target); - let glam = self.find_lib("glam", DepKind::SpirvLib, target); - let spirv_std_macros = self.find_lib("spirv_std_macros", DepKind::ProcMacro, target); - - let all_libs = [ - &compiler_builtins, - &core, - &spirv_std, - &glam, - &spirv_std_macros, - ]; - if all_libs.iter().any(|r| r.is_err()) { - // FIXME(eddyb) `missing_count` should always be `0` anyway. - // FIXME(eddyb) use `--message-format=json-render-diagnostics` to - // avoid caring about duplicates (or search within files at all). - let missing_count = all_libs - .iter() - .filter(|r| matches!(r, Err(FindLibError::Missing))) - .count(); - let duplicate_count = all_libs - .iter() - .filter(|r| matches!(r, Err(FindLibError::Duplicate))) - .count(); - eprintln!( - "warning: cleaning deps ({missing_count} missing libs, {duplicate_count} duplicated libs)" - ); + let all_deps: Result<_, ()> = (|| { + Ok([ + self.find_lib("compiler_builtins", DepKind::SpirvLib, target)? + .no_prelude(), + self.find_lib("core", DepKind::SpirvLib, target)? + .no_prelude(), + self.find_lib("spirv_std", DepKind::SpirvLib, target)?, + self.find_lib("glam", DepKind::SpirvLib, target)?, + self.find_lib("spirv_std_macros", DepKind::ProcMacro, target)?, + ]) + })(); + if let Ok(all_deps) = all_deps { + Vec::from(all_deps) + } else { + eprintln!("warning: cleaning and rebuilding deps"); self.clean_deps(); self.build_deps(target, target_spec) - } else { - TestDeps { - core: core.ok().unwrap(), - glam: glam.ok().unwrap(), - compiler_builtins: compiler_builtins.ok().unwrap(), - spirv_std: spirv_std.ok().unwrap(), - spirv_std_macros: spirv_std_macros.ok().unwrap(), - } } } @@ -271,29 +240,18 @@ impl Runner { } } -enum FindLibError { - Missing, - Duplicate, -} - impl Runner { /// Attempt find the rlib that matches `base`, if multiple rlibs are found then /// a clean build is required and `Err(FindLibError::Duplicate)` is returned. - fn find_lib( - &self, - base: impl AsRef, - dep_kind: DepKind, - target: &SpirvTarget, - ) -> Result { - let base = base.as_ref(); + fn find_lib(&self, name: &str, dep_kind: DepKind, target: &SpirvTarget) -> Result { let (expected_prefix, expected_extension) = dep_kind.prefix_and_extension(); - let expected_name = format!("{}{}", expected_prefix, base.display()); + let expected_prefix = format!("{expected_prefix}{name}"); let dir = self .deps_target_dir .join(dep_kind.target_dir_suffix(target)); - std::fs::read_dir(dir) + let rlib = std::fs::read_dir(dir) .unwrap() .map(|entry| entry.unwrap().path()) .filter(move |path| { @@ -305,9 +263,9 @@ impl Runner { name.unwrap() }; - let name_matches = name.to_str().unwrap().starts_with(&expected_name) - && name.len() == expected_name.len() + 17 // we expect our name, '-', and then 16 hexadecimal digits - && ends_with_dash_hash(name.to_str().unwrap()); + let name_matches = name.to_str().unwrap().starts_with(&expected_prefix) + && name.len() == expected_prefix.len() + 17 // we expect our name, '-', and then 16 hexadecimal digits + && ends_with_dash_hash(name.to_str().unwrap()); let extension_matches = path .extension() .is_some_and(|ext| ext == expected_extension); @@ -315,13 +273,8 @@ impl Runner { name_matches && extension_matches }) .exactly_one() - .map_err(|mut iter| { - if iter.next().is_none() { - FindLibError::Missing - } else { - FindLibError::Duplicate - } - }) + .map_err(|_e| ())?; + Ok(TestDep::new(name.to_owned(), rlib)) } } @@ -339,13 +292,32 @@ fn ends_with_dash_hash(s: &str) -> bool { bytes.all(|b| b.is_ascii_hexdigit()) } -/// Paths to all of the library artifacts of dependencies needed to compile tests. -struct TestDeps { - core: PathBuf, - compiler_builtins: PathBuf, - spirv_std: PathBuf, - spirv_std_macros: PathBuf, - glam: PathBuf, +struct TestDep { + name: String, + rlib: PathBuf, + no_prelude: bool, +} + +impl TestDep { + pub fn new(name: String, rlib: PathBuf) -> Self { + Self { + name, + rlib, + no_prelude: false, + } + } + + pub fn no_prelude(self) -> Self { + Self { + no_prelude: true, + ..self + } + } + + pub fn to_rustc_param(&self) -> String { + let noprelude = if self.no_prelude { "noprelude:" } else { "" }; + format!("--extern {noprelude}{}={}", self.name, self.rlib.display()) + } } /// The RUSTFLAGS passed to all SPIR-V builds. From b1b4261980c115d7997b98a0f3853831604d1364 Mon Sep 17 00:00:00 2001 From: firestar99 Date: Mon, 10 Aug 2026 14:56:21 +0200 Subject: [PATCH 2/2] new build dir compiletest: adjust for new build dir --- tests/compiletests/src/main.rs | 114 +++++++++++++++------------------ 1 file changed, 52 insertions(+), 62 deletions(-) diff --git a/tests/compiletests/src/main.rs b/tests/compiletests/src/main.rs index e290aa4ed51..1b3a37defd7 100644 --- a/tests/compiletests/src/main.rs +++ b/tests/compiletests/src/main.rs @@ -45,8 +45,8 @@ impl DepKind { fn target_dir_suffix(self, target: &SpirvTarget) -> String { match self { - Self::SpirvLib => format!("{}/debug/deps", target.target()), - Self::ProcMacro => "debug/deps".into(), + Self::SpirvLib => format!("{}/debug/build", target.target()), + Self::ProcMacro => "debug/build".into(), } } } @@ -102,16 +102,16 @@ impl Runner { fn test_rustc_flags( codegen_backend_path: &Path, deps: &[TestDep], - indirect_deps_dirs: &[&Path], + search_dirs: &[PathBuf], ) -> String { [ &*rust_flags(codegen_backend_path), - &*indirect_deps_dirs + &*search_dirs .iter() .map(|dir| format!("-L dependency={}", dir.display())) - .fold(String::new(), |a, b| b + " " + &a), + .join(" "), "--edition 2021", - &*deps.iter().map(TestDep::to_rustc_param).join(" "), + &*deps.iter().map(TestDep::to_rustc_extern).join(" "), "--crate-type dylib", "-Zunstable-options", "-Zcrate-attr=no_std", @@ -156,18 +156,8 @@ impl Runner { .unwrap(); let libs = self.build_deps(&target, &target_spec); - let mut flags = test_rustc_flags( - &self.codegen_backend_path, - &libs, - &[ - &self - .deps_target_dir - .join(DepKind::SpirvLib.target_dir_suffix(&target)), - &self - .deps_target_dir - .join(DepKind::ProcMacro.target_dir_suffix(&target)), - ], - ); + let search_dirs = self.dep_search_dirs(&target); + let mut flags = test_rustc_flags(&self.codegen_backend_path, &libs, &search_dirs); flags += variation.extra_flags; let config = compiletest::Config { @@ -198,6 +188,7 @@ impl Runner { "compiletests-deps-helper", "-Zbuild-std=core", "-Zbuild-std-features=compiler-builtins-mem", + "-Zbuild-dir-new-layout", ]); target_spec.append_to_cmd(&mut cmd); cmd.arg("--target-dir") @@ -215,9 +206,9 @@ impl Runner { .no_prelude(), self.find_lib("core", DepKind::SpirvLib, target)? .no_prelude(), - self.find_lib("spirv_std", DepKind::SpirvLib, target)?, + self.find_lib("spirv-std", DepKind::SpirvLib, target)?, self.find_lib("glam", DepKind::SpirvLib, target)?, - self.find_lib("spirv_std_macros", DepKind::ProcMacro, target)?, + self.find_lib("spirv-std-macros", DepKind::ProcMacro, target)?, ]) })(); if let Ok(all_deps) = all_deps { @@ -241,57 +232,56 @@ impl Runner { } impl Runner { + /// search for `out` dirs for all compiled libraries + fn dep_search_dirs(&self, target: &SpirvTarget) -> Vec { + [ + self.deps_target_dir + .join(DepKind::SpirvLib.target_dir_suffix(target)), + self.deps_target_dir + .join(DepKind::ProcMacro.target_dir_suffix(target)), + ] + .iter() + .filter_map(|build_dir| std::fs::read_dir(build_dir).ok()) + .flatten() + .filter_map(|crate_dir| std::fs::read_dir(crate_dir.ok()?.path()).ok()) + .flatten() + .filter_map(|hash_dir| { + let out_dir = hash_dir.ok()?.path().join("out"); + out_dir.is_dir().then_some(out_dir) + }) + .collect() + } + /// Attempt find the rlib that matches `base`, if multiple rlibs are found then /// a clean build is required and `Err(FindLibError::Duplicate)` is returned. fn find_lib(&self, name: &str, dep_kind: DepKind, target: &SpirvTarget) -> Result { - let (expected_prefix, expected_extension) = dep_kind.prefix_and_extension(); - let expected_prefix = format!("{expected_prefix}{name}"); - - let dir = self + let ident_name = name.replace("-", "_"); + let (expected_prefix, expected_suffix) = dep_kind.prefix_and_extension(); + let expected_prefix = format!("{expected_prefix}{}", ident_name); + let build_dir = self .deps_target_dir - .join(dep_kind.target_dir_suffix(target)); - - let rlib = std::fs::read_dir(dir) - .unwrap() - .map(|entry| entry.unwrap().path()) - .filter(move |path| { - let name = { - let name = path.file_stem(); - if name.is_none() { - return false; - } - name.unwrap() - }; - - let name_matches = name.to_str().unwrap().starts_with(&expected_prefix) - && name.len() == expected_prefix.len() + 17 // we expect our name, '-', and then 16 hexadecimal digits - && ends_with_dash_hash(name.to_str().unwrap()); - let extension_matches = path - .extension() - .is_some_and(|ext| ext == expected_extension); - - name_matches && extension_matches + .join(dep_kind.target_dir_suffix(target)) + .join(name); + + let rlib = std::fs::read_dir(&build_dir) + .unwrap_or_else(|_| panic!("Couldn't read dir {}", build_dir.display())) + .filter_map(|entry| { + let out_dir = entry.ok()?.path().join("out"); + std::fs::read_dir(out_dir).ok() + }) + .flatten() + .filter_map(|entry| { + let path = entry.ok()?.path(); + let file_name = path.file_name()?.to_str()?; + (file_name.starts_with(&expected_prefix) && file_name.ends_with(expected_suffix)) + .then_some(path) }) .exactly_one() .map_err(|_e| ())?; - Ok(TestDep::new(name.to_owned(), rlib)) + Ok(TestDep::new(ident_name, rlib)) } } -/// Returns whether this string ends with a dash ('-'), followed by 16 lowercase hexadecimal characters -fn ends_with_dash_hash(s: &str) -> bool { - let n = s.len(); - if n < 17 { - return false; - } - let mut bytes = s.bytes().skip(n - 17); - if bytes.next() != Some(b'-') { - return false; - } - - bytes.all(|b| b.is_ascii_hexdigit()) -} - struct TestDep { name: String, rlib: PathBuf, @@ -314,7 +304,7 @@ impl TestDep { } } - pub fn to_rustc_param(&self) -> String { + pub fn to_rustc_extern(&self) -> String { let noprelude = if self.no_prelude { "noprelude:" } else { "" }; format!("--extern {noprelude}{}={}", self.name, self.rlib.display()) }