11use clap:: Parser ;
22use itertools:: Itertools as _;
3- use rustc_codegen_spirv_target_specs:: TARGET_SPEC_DIR_PATH ;
3+ use rustc_codegen_spirv_types:: { Target , TargetSpecVersion , query_rustc_version} ;
4+ use std:: ffi:: OsString ;
45use std:: {
56 env, io,
67 path:: { Path , PathBuf } ,
@@ -28,12 +29,6 @@ impl Opt {
2829 }
2930}
3031
31- const SPIRV_TARGET_PREFIX : & str = "spirv-unknown-" ;
32-
33- fn target_spec_json ( target : & str ) -> String {
34- format ! ( "{TARGET_SPEC_DIR_PATH}/{target}.json" )
35- }
36-
3732#[ derive( Copy , Clone ) ]
3833enum DepKind {
3934 SpirvLib ,
@@ -48,9 +43,9 @@ impl DepKind {
4843 }
4944 }
5045
51- fn target_dir_suffix ( self , target : & str ) -> String {
46+ fn target_dir_suffix ( self , target : & Target ) -> String {
5247 match self {
53- Self :: SpirvLib => format ! ( "{target }/debug/deps" ) ,
48+ Self :: SpirvLib => format ! ( "{}/debug/deps" , target . target ( ) ) ,
5449 Self :: ProcMacro => "debug/deps" . into ( ) ,
5550 }
5651 }
@@ -161,8 +156,8 @@ impl Runner {
161156
162157 println ! ( "Testing env: {stage_id}\n " ) ;
163158
164- let target = format ! ( "{SPIRV_TARGET_PREFIX}{ env}" ) ;
165- let libs = build_deps ( & self . deps_target_dir , & self . codegen_backend_path , & target) ;
159+ let target = Target :: from_env ( env) . unwrap ( ) ;
160+ let libs = self . build_deps ( & target) ;
166161 let mut flags = test_rustc_flags (
167162 & self . codegen_backend_path ,
168163 & libs,
@@ -181,7 +176,7 @@ impl Runner {
181176 stage_id,
182177 target_rustcflags : Some ( flags) ,
183178 mode : mode. parse ( ) . expect ( "Invalid mode" ) ,
184- target : target_spec_json ( & target) ,
179+ target : self . target_spec_json ( & target) . into_string ( ) . unwrap ( ) ,
185180 src_base : self . tests_dir . join ( mode) ,
186181 build_base : self . compiletest_build_dir . clone ( ) ,
187182 bless : self . opt . bless ,
@@ -194,142 +189,140 @@ impl Runner {
194189 compiletest:: run_tests ( & config) ;
195190 }
196191 }
197- }
198192
199- /// Runs the processes needed to build `spirv-std` & other deps.
200- fn build_deps ( deps_target_dir : & Path , codegen_backend_path : & Path , target : & str ) -> TestDeps {
201- // Build compiletests-deps-helper
202- std:: process:: Command :: new ( "cargo" )
203- . args ( [
204- "build" ,
205- "-p" ,
206- "compiletests-deps-helper" ,
207- "-Zbuild-std=core" ,
208- "-Zbuild-std-features=compiler-builtins-mem" ,
209- & * format ! ( "--target={}" , target_spec_json( target) ) ,
210- ] )
211- . arg ( "--target-dir" )
212- . arg ( deps_target_dir)
213- . env ( "RUSTFLAGS" , rust_flags ( codegen_backend_path) )
214- . stderr ( std:: process:: Stdio :: inherit ( ) )
215- . stdout ( std:: process:: Stdio :: inherit ( ) )
216- . status ( )
217- . and_then ( map_status_to_result)
218- . unwrap ( ) ;
219-
220- let compiler_builtins = find_lib (
221- deps_target_dir,
222- "compiler_builtins" ,
223- DepKind :: SpirvLib ,
224- target,
225- ) ;
226- let core = find_lib ( deps_target_dir, "core" , DepKind :: SpirvLib , target) ;
227- let spirv_std = find_lib ( deps_target_dir, "spirv_std" , DepKind :: SpirvLib , target) ;
228- let glam = find_lib ( deps_target_dir, "glam" , DepKind :: SpirvLib , target) ;
229- let spirv_std_macros = find_lib (
230- deps_target_dir,
231- "spirv_std_macros" ,
232- DepKind :: ProcMacro ,
233- target,
234- ) ;
193+ fn target_spec_json ( & self , target : & Target ) -> OsString {
194+ let rustc_version = query_rustc_version ( None ) . unwrap ( ) ;
195+ TargetSpecVersion :: target_arg ( rustc_version, target, & self . deps_target_dir ) . unwrap ( )
196+ }
235197
236- let all_libs = [
237- & compiler_builtins,
238- & core,
239- & spirv_std,
240- & glam,
241- & spirv_std_macros,
242- ] ;
243- if all_libs. iter ( ) . any ( |r| r. is_err ( ) ) {
244- // FIXME(eddyb) `missing_count` should always be `0` anyway.
245- // FIXME(eddyb) use `--message-format=json-render-diagnostics` to
246- // avoid caring about duplicates (or search within files at all).
247- let missing_count = all_libs
248- . iter ( )
249- . filter ( |r| matches ! ( r, Err ( FindLibError :: Missing ) ) )
250- . count ( ) ;
251- let duplicate_count = all_libs
252- . iter ( )
253- . filter ( |r| matches ! ( r, Err ( FindLibError :: Duplicate ) ) )
254- . count ( ) ;
255- eprintln ! (
256- "warning: cleaning deps ({missing_count} missing libs, {duplicate_count} duplicated libs)"
257- ) ;
258- clean_deps ( deps_target_dir) ;
259- build_deps ( deps_target_dir, codegen_backend_path, target)
260- } else {
261- TestDeps {
262- core : core. ok ( ) . unwrap ( ) ,
263- glam : glam. ok ( ) . unwrap ( ) ,
264- compiler_builtins : compiler_builtins. ok ( ) . unwrap ( ) ,
265- spirv_std : spirv_std. ok ( ) . unwrap ( ) ,
266- spirv_std_macros : spirv_std_macros. ok ( ) . unwrap ( ) ,
198+ /// Runs the processes needed to build `spirv-std` & other deps.
199+ fn build_deps ( & self , target : & Target ) -> TestDeps {
200+ // Build compiletests-deps-helper
201+ std:: process:: Command :: new ( "cargo" )
202+ . args ( [
203+ "build" ,
204+ "-p" ,
205+ "compiletests-deps-helper" ,
206+ "-Zbuild-std=core" ,
207+ "-Zbuild-std-features=compiler-builtins-mem" ,
208+ "--target" ,
209+ ] )
210+ . arg ( self . target_spec_json ( target) )
211+ . arg ( "--target-dir" )
212+ . arg ( & self . deps_target_dir )
213+ . env ( "RUSTFLAGS" , rust_flags ( & self . codegen_backend_path ) )
214+ . stderr ( std:: process:: Stdio :: inherit ( ) )
215+ . stdout ( std:: process:: Stdio :: inherit ( ) )
216+ . status ( )
217+ . and_then ( map_status_to_result)
218+ . unwrap ( ) ;
219+
220+ let compiler_builtins = self . find_lib ( "compiler_builtins" , DepKind :: SpirvLib , target) ;
221+ let core = self . find_lib ( "core" , DepKind :: SpirvLib , target) ;
222+ let spirv_std = self . find_lib ( "spirv_std" , DepKind :: SpirvLib , target) ;
223+ let glam = self . find_lib ( "glam" , DepKind :: SpirvLib , target) ;
224+ let spirv_std_macros = self . find_lib ( "spirv_std_macros" , DepKind :: ProcMacro , target) ;
225+
226+ let all_libs = [
227+ & compiler_builtins,
228+ & core,
229+ & spirv_std,
230+ & glam,
231+ & spirv_std_macros,
232+ ] ;
233+ if all_libs. iter ( ) . any ( |r| r. is_err ( ) ) {
234+ // FIXME(eddyb) `missing_count` should always be `0` anyway.
235+ // FIXME(eddyb) use `--message-format=json-render-diagnostics` to
236+ // avoid caring about duplicates (or search within files at all).
237+ let missing_count = all_libs
238+ . iter ( )
239+ . filter ( |r| matches ! ( r, Err ( FindLibError :: Missing ) ) )
240+ . count ( ) ;
241+ let duplicate_count = all_libs
242+ . iter ( )
243+ . filter ( |r| matches ! ( r, Err ( FindLibError :: Duplicate ) ) )
244+ . count ( ) ;
245+ eprintln ! (
246+ "warning: cleaning deps ({missing_count} missing libs, {duplicate_count} duplicated libs)"
247+ ) ;
248+ self . clean_deps ( ) ;
249+ self . build_deps ( target)
250+ } else {
251+ TestDeps {
252+ core : core. ok ( ) . unwrap ( ) ,
253+ glam : glam. ok ( ) . unwrap ( ) ,
254+ compiler_builtins : compiler_builtins. ok ( ) . unwrap ( ) ,
255+ spirv_std : spirv_std. ok ( ) . unwrap ( ) ,
256+ spirv_std_macros : spirv_std_macros. ok ( ) . unwrap ( ) ,
257+ }
267258 }
268259 }
269- }
270260
271- fn clean_deps ( deps_target_dir : & Path ) {
272- std:: process:: Command :: new ( "cargo" )
273- . arg ( "clean" )
274- . arg ( "--target-dir" )
275- . arg ( deps_target_dir)
276- . stderr ( std:: process:: Stdio :: inherit ( ) )
277- . stdout ( std:: process:: Stdio :: inherit ( ) )
278- . status ( )
279- . and_then ( map_status_to_result)
280- . unwrap ( ) ;
261+ fn clean_deps ( & self ) {
262+ std:: process:: Command :: new ( "cargo" )
263+ . arg ( "clean" )
264+ . arg ( "--target-dir" )
265+ . arg ( & self . deps_target_dir )
266+ . stderr ( std:: process:: Stdio :: inherit ( ) )
267+ . stdout ( std:: process:: Stdio :: inherit ( ) )
268+ . status ( )
269+ . and_then ( map_status_to_result)
270+ . unwrap ( ) ;
271+ }
272+
273+ /// Attempt find the rlib that matches `base`, if multiple rlibs are found then
274+ /// a clean build is required and `Err(FindLibError::Duplicate)` is returned.
275+ fn find_lib (
276+ & self ,
277+ base : impl AsRef < Path > ,
278+ dep_kind : DepKind ,
279+ target : & Target ,
280+ ) -> Result < PathBuf , FindLibError > {
281+ let base = base. as_ref ( ) ;
282+ let ( expected_prefix, expected_extension) = dep_kind. prefix_and_extension ( ) ;
283+ let expected_name = format ! ( "{}{}" , expected_prefix, base. display( ) ) ;
284+
285+ let dir = self
286+ . deps_target_dir
287+ . join ( dep_kind. target_dir_suffix ( target) ) ;
288+
289+ std:: fs:: read_dir ( dir)
290+ . unwrap ( )
291+ . map ( |entry| entry. unwrap ( ) . path ( ) )
292+ . filter ( move |path| {
293+ let name = {
294+ let name = path. file_stem ( ) ;
295+ if name. is_none ( ) {
296+ return false ;
297+ }
298+ name. unwrap ( )
299+ } ;
300+
301+ let name_matches = name. to_str ( ) . unwrap ( ) . starts_with ( & expected_name)
302+ && name. len ( ) == expected_name. len ( ) + 17 // we expect our name, '-', and then 16 hexadecimal digits
303+ && ends_with_dash_hash ( name. to_str ( ) . unwrap ( ) ) ;
304+ let extension_matches = path
305+ . extension ( )
306+ . is_some_and ( |ext| ext == expected_extension) ;
307+
308+ name_matches && extension_matches
309+ } )
310+ . exactly_one ( )
311+ . map_err ( |mut iter| {
312+ if iter. next ( ) . is_none ( ) {
313+ FindLibError :: Missing
314+ } else {
315+ FindLibError :: Duplicate
316+ }
317+ } )
318+ }
281319}
282320
283321enum FindLibError {
284322 Missing ,
285323 Duplicate ,
286324}
287325
288- /// Attempt find the rlib that matches `base`, if multiple rlibs are found then
289- /// a clean build is required and `Err(FindLibError::Duplicate)` is returned.
290- fn find_lib (
291- deps_target_dir : & Path ,
292- base : impl AsRef < Path > ,
293- dep_kind : DepKind ,
294- target : & str ,
295- ) -> Result < PathBuf , FindLibError > {
296- let base = base. as_ref ( ) ;
297- let ( expected_prefix, expected_extension) = dep_kind. prefix_and_extension ( ) ;
298- let expected_name = format ! ( "{}{}" , expected_prefix, base. display( ) ) ;
299-
300- let dir = deps_target_dir. join ( dep_kind. target_dir_suffix ( target) ) ;
301-
302- std:: fs:: read_dir ( dir)
303- . unwrap ( )
304- . map ( |entry| entry. unwrap ( ) . path ( ) )
305- . filter ( move |path| {
306- let name = {
307- let name = path. file_stem ( ) ;
308- if name. is_none ( ) {
309- return false ;
310- }
311- name. unwrap ( )
312- } ;
313-
314- let name_matches = name. to_str ( ) . unwrap ( ) . starts_with ( & expected_name)
315- && name. len ( ) == expected_name. len ( ) + 17 // we expect our name, '-', and then 16 hexadecimal digits
316- && ends_with_dash_hash ( name. to_str ( ) . unwrap ( ) ) ;
317- let extension_matches = path
318- . extension ( )
319- . is_some_and ( |ext| ext == expected_extension) ;
320-
321- name_matches && extension_matches
322- } )
323- . exactly_one ( )
324- . map_err ( |mut iter| {
325- if iter. next ( ) . is_none ( ) {
326- FindLibError :: Missing
327- } else {
328- FindLibError :: Duplicate
329- }
330- } )
331- }
332-
333326/// Returns whether this string ends with a dash ('-'), followed by 16 lowercase hexadecimal characters
334327fn ends_with_dash_hash ( s : & str ) -> bool {
335328 let n = s. len ( ) ;
0 commit comments