Skip to content

Commit 9e3bb73

Browse files
committed
spirv-builder: make required extra arg -Zjson-target-spec backwards compatible
1 parent 85cd195 commit 9e3bb73

File tree

3 files changed

+48
-27
lines changed

3 files changed

+48
-27
lines changed

crates/rustc_codegen_spirv-types/src/target_spec.rs

Lines changed: 39 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
11
use crate::SpirvTarget;
22
use semver::Version;
3-
use std::ffi::OsString;
3+
use std::ffi::OsStr;
44
use 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)]
1111
pub 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,67 @@ 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-lang/rust/pull/150151
24+
Rustc_1_94_0,
2125
}
2226

2327
impl TargetSpecVersion {
2428
/// Format the `--target` arg. On newer rustc versions, will create a compatible target spec json file and return
2529
/// the absolute path to it, on older rustc versions may return the target name.
26-
pub fn target_arg(
30+
pub fn append_target_arg(
2731
rustc_version: Version,
2832
target: &SpirvTarget,
2933
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()))
34+
mut push_arg: impl FnMut(&OsStr),
35+
) -> std::io::Result<()> {
36+
let target_spec = Self::from_rustc_version(rustc_version);
37+
if target_spec >= Self::Rustc_1_94_0 {
38+
push_arg("-Zjson-target-spec".as_ref());
39+
}
40+
41+
push_arg("--target".as_ref());
42+
match target_spec {
43+
TargetSpecVersion::Older => {
44+
push_arg(target.target().as_ref());
45+
}
46+
_ => {
47+
std::fs::create_dir_all(target_spec_folder)?;
48+
let spec_file = target_spec_folder.join(format!("{}.json", target.target()));
49+
std::fs::write(&spec_file, target_spec.format_spec(target))?;
50+
let spec_file = std::fs::canonicalize(spec_file)?.into_os_string();
51+
push_arg(&spec_file);
52+
}
3853
}
54+
Ok(())
3955
}
4056

4157
/// Returns the version of the target spec required for a certain rustc version. May return `None` if the version
4258
/// 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)
59+
pub fn from_rustc_version(rustc_version: Version) -> Self {
60+
if rustc_version >= Version::new(1, 94, 0) {
61+
Self::Rustc_1_94_0
62+
} else if rustc_version >= Version::new(1, 93, 0) {
63+
Self::Rustc_1_93_0
4664
} else if rustc_version >= Version::new(1, 85, 0) {
47-
Some(Self::Rustc_1_85_0)
65+
Self::Rustc_1_85_0
4866
} else if rustc_version >= Version::new(1, 76, 0) {
49-
Some(Self::Rustc_1_76_0)
67+
Self::Rustc_1_76_0
5068
} else {
51-
None
69+
Self::Older
5270
}
5371
}
5472

5573
/// format the target spec json
5674
pub fn format_spec(&self, target: &SpirvTarget) -> String {
5775
let target_env = target.env();
5876
let (extra, target_pointer_width) = match self {
77+
TargetSpecVersion::Older => panic!("no target specs for older rustc versions"),
5978
TargetSpecVersion::Rustc_1_76_0 => (r#""os": "unknown","#, "\"32\""),
6079
TargetSpecVersion::Rustc_1_85_0 => (r#""crt-static-respected": true,"#, "\"32\""),
61-
TargetSpecVersion::Rustc_1_93_0 => (r#""crt-static-respected": true,"#, "32"),
80+
TargetSpecVersion::Rustc_1_93_0 | TargetSpecVersion::Rustc_1_94_0 => {
81+
(r#""crt-static-respected": true,"#, "32")
82+
}
6283
};
6384
format!(
6485
r#"{{

crates/spirv-builder/src/lib.rs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1046,14 +1046,14 @@ fn invoke_rustc(builder: &SpirvBuilder) -> Result<PathBuf, SpirvBuilderError> {
10461046
}
10471047

10481048
let target_spec_dir = target_dir.join("target-specs");
1049-
let target = TargetSpecVersion::target_arg(toolchain_rustc_version, &target, &target_spec_dir)?;
1050-
if Path::new(&target)
1051-
.extension()
1052-
.is_some_and(|ext| ext == "json")
1053-
{
1054-
cargo.arg("-Zjson-target-spec");
1055-
}
1056-
cargo.arg("--target").arg(target);
1049+
TargetSpecVersion::append_target_arg(
1050+
toolchain_rustc_version,
1051+
&target,
1052+
&target_spec_dir,
1053+
|arg| {
1054+
cargo.arg(arg);
1055+
},
1056+
)?;
10571057

10581058
if !builder.shader_crate_features.default_features {
10591059
cargo.arg("--no-default-features");

tests/compiletests/src/main.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -268,7 +268,7 @@ impl Runner {
268268

269269
fn target_spec_json(&self, target: &SpirvTarget) -> OsString {
270270
let rustc_version = query_rustc_version(None).unwrap();
271-
TargetSpecVersion::target_arg(rustc_version, target, &self.deps_target_dir).unwrap()
271+
TargetSpecVersion::append_target_arg(rustc_version, target, &self.deps_target_dir).unwrap()
272272
}
273273
}
274274

0 commit comments

Comments
 (0)