Skip to content

Commit 99993ee

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

File tree

3 files changed

+72
-51
lines changed

3 files changed

+72
-51
lines changed

crates/rustc_codegen_spirv-types/src/target_spec.rs

Lines changed: 45 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,9 @@ use std::path::Path;
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,6 +19,24 @@ 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,
26+
}
27+
28+
#[derive(Clone, Debug, Default)]
29+
pub struct TargetSpec {
30+
pub target: OsString,
31+
pub extra_options: Vec<OsString>,
32+
}
33+
34+
impl TargetSpec {
35+
pub fn append_to_cmd(&self, cmd: &mut std::process::Command) {
36+
cmd.args(self.extra_options.iter());
37+
cmd.arg("--target");
38+
cmd.arg(&self.target);
39+
}
2140
}
2241

2342
impl TargetSpecVersion {
@@ -27,38 +46,50 @@ impl TargetSpecVersion {
2746
rustc_version: Version,
2847
target: &SpirvTarget,
2948
target_spec_folder: &Path,
30-
) -> std::io::Result<OsString> {
31-
if let Some(target_spec) = Self::from_rustc_version(rustc_version) {
49+
) -> std::io::Result<TargetSpec> {
50+
let mut ret = TargetSpec::default();
51+
let target_spec = Self::from_rustc_version(rustc_version);
52+
if target_spec >= Self::Rustc_1_94_0 {
53+
ret.extra_options.push("-Zjson-target-spec".into());
54+
}
55+
56+
ret.target = if target_spec == Self::Older {
57+
target.target().into()
58+
} else {
3259
std::fs::create_dir_all(target_spec_folder)?;
3360
let spec_file = target_spec_folder.join(format!("{}.json", target.target()));
3461
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()))
38-
}
62+
std::fs::canonicalize(spec_file)?.into_os_string()
63+
};
64+
Ok(ret)
3965
}
4066

4167
/// Returns the version of the target spec required for a certain rustc version. May return `None` if the version
4268
/// 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)
69+
pub fn from_rustc_version(rustc_version: Version) -> Self {
70+
if rustc_version >= Version::new(1, 94, 0) {
71+
Self::Rustc_1_94_0
72+
} else if rustc_version >= Version::new(1, 93, 0) {
73+
Self::Rustc_1_93_0
4674
} else if rustc_version >= Version::new(1, 85, 0) {
47-
Some(Self::Rustc_1_85_0)
75+
Self::Rustc_1_85_0
4876
} else if rustc_version >= Version::new(1, 76, 0) {
49-
Some(Self::Rustc_1_76_0)
77+
Self::Rustc_1_76_0
5078
} else {
51-
None
79+
Self::Older
5280
}
5381
}
5482

5583
/// format the target spec json
5684
pub fn format_spec(&self, target: &SpirvTarget) -> String {
5785
let target_env = target.env();
5886
let (extra, target_pointer_width) = match self {
87+
TargetSpecVersion::Older => panic!("no target specs for older rustc versions"),
5988
TargetSpecVersion::Rustc_1_76_0 => (r#""os": "unknown","#, "\"32\""),
6089
TargetSpecVersion::Rustc_1_85_0 => (r#""crt-static-respected": true,"#, "\"32\""),
61-
TargetSpecVersion::Rustc_1_93_0 => (r#""crt-static-respected": true,"#, "32"),
90+
TargetSpecVersion::Rustc_1_93_0 | TargetSpecVersion::Rustc_1_94_0 => {
91+
(r#""crt-static-respected": true,"#, "32")
92+
}
6293
};
6394
format!(
6495
r#"{{

crates/spirv-builder/src/lib.rs

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1046,14 +1046,8 @@ 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+
let target_spec = TargetSpecVersion::target_arg(toolchain_rustc_version, &target, &target_spec_dir)?;
1050+
target_spec.append_to_cmd(&mut cargo);
10571051

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

tests/compiletests/src/main.rs

Lines changed: 25 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use clap::Parser;
2+
use compiletest::common::Mode;
23
use itertools::Itertools as _;
3-
use rustc_codegen_spirv_types::{SpirvTarget, TargetSpecVersion, query_rustc_version};
4-
use std::ffi::OsString;
4+
use rustc_codegen_spirv_types::{SpirvTarget, TargetSpec, TargetSpecVersion, query_rustc_version};
55
use std::{
66
env, io,
77
path::{Path, PathBuf},
@@ -79,7 +79,7 @@ fn main() {
7979
codegen_backend_path,
8080
};
8181

82-
runner.run_mode("ui");
82+
runner.run_mode(Mode::Ui);
8383
}
8484

8585
struct Runner {
@@ -94,7 +94,7 @@ impl Runner {
9494
/// Runs the given `mode` on the directory that matches that name, using the
9595
/// backend provided by `codegen_backend_path`.
9696
#[allow(clippy::string_add)]
97-
fn run_mode(&self, mode: &'static str) {
97+
fn run_mode(&self, mode: Mode) {
9898
/// RUSTFLAGS passed to all test files.
9999
fn test_rustc_flags(
100100
codegen_backend_path: &Path,
@@ -157,7 +157,12 @@ impl Runner {
157157
println!("Testing env: {stage_id}\n");
158158

159159
let target = SpirvTarget::parse(env).unwrap();
160-
let libs = self.build_deps(&target);
160+
let rustc_version = query_rustc_version(None).unwrap();
161+
let target_spec =
162+
TargetSpecVersion::target_arg(rustc_version, &target, &self.deps_target_dir)
163+
.unwrap();
164+
165+
let libs = self.build_deps(&target, &target_spec);
161166
let mut flags = test_rustc_flags(
162167
&self.codegen_backend_path,
163168
&libs,
@@ -175,9 +180,9 @@ impl Runner {
175180
let config = compiletest::Config {
176181
stage_id,
177182
target_rustcflags: Some(flags),
178-
mode: mode.parse().expect("Invalid mode"),
179-
target: self.target_spec_json(&target).into_string().unwrap(),
180-
src_base: self.tests_dir.join(mode),
183+
mode,
184+
target: target_spec.target.into_string().unwrap(),
185+
src_base: self.tests_dir.join(mode.to_string()),
181186
build_base: self.compiletest_build_dir.clone(),
182187
bless: self.opt.bless,
183188
filters: self.opt.filters.clone(),
@@ -191,20 +196,18 @@ impl Runner {
191196
}
192197

193198
/// Runs the processes needed to build `spirv-std` & other deps.
194-
fn build_deps(&self, target: &SpirvTarget) -> TestDeps {
199+
fn build_deps(&self, target: &SpirvTarget, target_spec: &TargetSpec) -> TestDeps {
195200
// Build compiletests-deps-helper
196-
std::process::Command::new("cargo")
197-
.args([
198-
"build",
199-
"-p",
200-
"compiletests-deps-helper",
201-
"-Zjson-target-spec",
202-
"-Zbuild-std=core",
203-
"-Zbuild-std-features=compiler-builtins-mem",
204-
"--target",
205-
])
206-
.arg(self.target_spec_json(target))
207-
.arg("--target-dir")
201+
let mut cmd = std::process::Command::new("cargo");
202+
cmd.args([
203+
"build",
204+
"-p",
205+
"compiletests-deps-helper",
206+
"-Zbuild-std=core",
207+
"-Zbuild-std-features=compiler-builtins-mem",
208+
]);
209+
target_spec.append_to_cmd(&mut cmd);
210+
cmd.arg("--target-dir")
208211
.arg(&self.deps_target_dir)
209212
.env("RUSTFLAGS", rust_flags(&self.codegen_backend_path))
210213
.stderr(std::process::Stdio::inherit())
@@ -242,7 +245,7 @@ impl Runner {
242245
"warning: cleaning deps ({missing_count} missing libs, {duplicate_count} duplicated libs)"
243246
);
244247
self.clean_deps();
245-
self.build_deps(target)
248+
self.build_deps(target, target_spec)
246249
} else {
247250
TestDeps {
248251
core: core.ok().unwrap(),
@@ -259,17 +262,10 @@ impl Runner {
259262
.arg("clean")
260263
.arg("--target-dir")
261264
.arg(&self.deps_target_dir)
262-
.stderr(std::process::Stdio::inherit())
263-
.stdout(std::process::Stdio::inherit())
264265
.status()
265266
.and_then(map_status_to_result)
266267
.unwrap();
267268
}
268-
269-
fn target_spec_json(&self, target: &SpirvTarget) -> OsString {
270-
let rustc_version = query_rustc_version(None).unwrap();
271-
TargetSpecVersion::target_arg(rustc_version, target, &self.deps_target_dir).unwrap()
272-
}
273269
}
274270

275271
enum FindLibError {

0 commit comments

Comments
 (0)