11use crate :: SpirvTarget ;
22use semver:: Version ;
3- use std:: ffi:: OsString ;
3+ use std:: ffi:: OsStr ;
44use std:: path:: Path ;
55
66/// Enum for different versions of target specs, to allow changing the target spec for different rust versions.
77/// The version listed in the enum is always the minimum version to require said target spec, with the newest version
88/// always at the top.
99#[ allow( non_camel_case_types) ]
10- #[ derive( Copy , Clone , Debug ) ]
10+ #[ derive( Copy , Clone , Debug , Eq , PartialEq , Ord , PartialOrd ) ]
1111pub enum TargetSpecVersion {
12+ Older ,
1213 /// Introduced in `489c3ee6fd63da3ca7cf2b15e1ee709d8e078aab` in the old v2 target spec way, later ported to here.
1314 /// remove `os: unknown`, add `crt-static-respected: true`
1415 Rustc_1_85_0 ,
@@ -18,47 +19,68 @@ pub enum TargetSpecVersion {
1819 Rustc_1_76_0 ,
1920 /// rustc 1.93 requires that the value of "target-pointer-width" is no longer a string but u16
2021 Rustc_1_93_0 ,
22+ /// rustc 1.94.0 destabilised json target specs, requiring `-Ztarget-spec-json`
23+ /// see https://github.com/Rust-GPU/rust-gpu/pull/545
24+ /// see https://github.com/rust-lang/rust/pull/150151
25+ Rustc_1_94_0 ,
2126}
2227
2328impl TargetSpecVersion {
2429 /// Format the `--target` arg. On newer rustc versions, will create a compatible target spec json file and return
2530 /// the absolute path to it, on older rustc versions may return the target name.
26- pub fn target_arg (
31+ pub fn append_target_arg (
2732 rustc_version : Version ,
2833 target : & SpirvTarget ,
2934 target_spec_folder : & Path ,
30- ) -> std:: io:: Result < OsString > {
31- if let Some ( target_spec) = Self :: from_rustc_version ( rustc_version) {
32- std:: fs:: create_dir_all ( target_spec_folder) ?;
33- let spec_file = target_spec_folder. join ( format ! ( "{}.json" , target. target( ) ) ) ;
34- std:: fs:: write ( & spec_file, target_spec. format_spec ( target) ) ?;
35- Ok ( std:: fs:: canonicalize ( spec_file) ?. into_os_string ( ) )
36- } else {
37- Ok ( OsString :: from ( target. target ( ) ) )
35+ mut push_arg : impl FnMut ( & OsStr ) ,
36+ ) -> std:: io:: Result < ( ) > {
37+ let target_spec = Self :: from_rustc_version ( rustc_version) ;
38+ if target_spec >= Self :: Rustc_1_94_0 {
39+ push_arg ( "-Zjson-target-spec" . as_ref ( ) ) ;
40+ }
41+
42+ push_arg ( "--target" . as_ref ( ) ) ;
43+ match target_spec {
44+ TargetSpecVersion :: Older => {
45+ push_arg ( target. target ( ) . as_ref ( ) ) ;
46+ }
47+ _ => {
48+ std:: fs:: create_dir_all ( target_spec_folder) ?;
49+ let spec_file = target_spec_folder. join ( format ! ( "{}.json" , target. target( ) ) ) ;
50+ std:: fs:: write ( & spec_file, target_spec. format_spec ( target) ) ?;
51+ let spec_file = std:: fs:: canonicalize ( spec_file) ?. into_os_string ( ) ;
52+ push_arg ( & spec_file) ;
53+ }
3854 }
55+ Ok ( ( ) )
3956 }
4057
4158 /// Returns the version of the target spec required for a certain rustc version. May return `None` if the version
4259 /// is old enough to not need target specs.
43- pub fn from_rustc_version ( rustc_version : Version ) -> Option < Self > {
44- if rustc_version >= Version :: new ( 1 , 93 , 0 ) {
45- Some ( Self :: Rustc_1_93_0 )
60+ pub fn from_rustc_version ( rustc_version : Version ) -> Self {
61+ if rustc_version >= Version :: new ( 1 , 94 , 0 ) {
62+ Self :: Rustc_1_94_0
63+ } else if rustc_version >= Version :: new ( 1 , 93 , 0 ) {
64+ Self :: Rustc_1_93_0
4665 } else if rustc_version >= Version :: new ( 1 , 85 , 0 ) {
47- Some ( Self :: Rustc_1_85_0 )
66+ Self :: Rustc_1_85_0
4867 } else if rustc_version >= Version :: new ( 1 , 76 , 0 ) {
49- Some ( Self :: Rustc_1_76_0 )
68+ Self :: Rustc_1_76_0
5069 } else {
51- None
70+ Self :: Older
5271 }
5372 }
5473
5574 /// format the target spec json
5675 pub fn format_spec ( & self , target : & SpirvTarget ) -> String {
5776 let target_env = target. env ( ) ;
5877 let ( extra, target_pointer_width) = match self {
78+ TargetSpecVersion :: Older => panic ! ( "no target specs for older rustc versions" ) ,
5979 TargetSpecVersion :: Rustc_1_76_0 => ( r#""os": "unknown","# , "\" 32\" " ) ,
6080 TargetSpecVersion :: Rustc_1_85_0 => ( r#""crt-static-respected": true,"# , "\" 32\" " ) ,
61- TargetSpecVersion :: Rustc_1_93_0 => ( r#""crt-static-respected": true,"# , "32" ) ,
81+ TargetSpecVersion :: Rustc_1_93_0 | TargetSpecVersion :: Rustc_1_94_0 => {
82+ ( r#""crt-static-respected": true,"# , "32" )
83+ }
6284 } ;
6385 format ! (
6486 r#"{{
0 commit comments