Skip to content

Updating target json support #256

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
May 29, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ members = [

"crates/rustc_codegen_spirv",
"crates/rustc_codegen_spirv-types",
"crates/rustc_codegen_spirv-target-specs",
"crates/spirv-builder",
"crates/spirv-std",
"crates/spirv-std/shared",
Expand Down Expand Up @@ -46,6 +47,7 @@ spirv-std-macros = { path = "./crates/spirv-std/macros", version = "=0.9.0" }
spirv-tools = { version = "0.11", default-features = false }
rustc_codegen_spirv = { path = "./crates/rustc_codegen_spirv", version = "=0.9.0", default-features = false }
rustc_codegen_spirv-types = { path = "./crates/rustc_codegen_spirv-types", version = "=0.9.0" }
rustc_codegen_spirv-target-specs = { path = "crates/rustc_codegen_spirv-target-specs", version = "=0.9.0" }
tracing = "0.1"
tracing-subscriber = { version = "0.3.3", features = ["env-filter", "json"] }

Expand Down
12 changes: 12 additions & 0 deletions crates/rustc_codegen_spirv-target-specs/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
[package]
name = "rustc_codegen_spirv-target-specs"
description = "target spec json files of rust-gpu for the rustc compiler"
version.workspace = true
authors.workspace = true
edition.workspace = true
license.workspace = true
repository.workspace = true

[features]
include_str = []
dir_path = []
7 changes: 7 additions & 0 deletions crates/rustc_codegen_spirv-target-specs/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# `rustc_codegen_spirv-target-specs`

The target spec json files of rust-gpu to hand to the rustc compiler, declaring various metadata about our codegen backend.

## Features
* `include_str`: include target specs as string constants, for bundling with `cargo-gpu`
* `dir_path`: export a path to the target specs dir, for `spirv-builder` and `compiletest` in this repo
10 changes: 10 additions & 0 deletions crates/rustc_codegen_spirv-target-specs/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#![doc = include_str!("../README.md")]

/// directory with all the `target-specs` jsons for our codegen backend
#[cfg(feature = "dir_path")]
pub const TARGET_SPEC_DIR_PATH: &str = concat!(env!("CARGO_MANIFEST_DIR"), "/target-specs");

#[cfg(feature = "include_str")]
mod include_str;
#[cfg(feature = "include_str")]
pub use include_str::TARGET_SPECS;
3 changes: 3 additions & 0 deletions crates/rustc_codegen_spirv/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,9 @@ tracing.workspace = true
tracing-subscriber.workspace = true
tracing-tree = "0.3.0"

# required for cargo gpu to resolve the needed target specs
rustc_codegen_spirv-target-specs.workspace = true

[dev-dependencies]
pretty_assertions = "1.0"

Expand Down
18 changes: 10 additions & 8 deletions crates/spirv-builder/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,21 +22,23 @@ default = ["use-compiled-tools"]
# Compile `rustc_codegen_spirv`, allows constructing SpirvBuilder without
# explicitly passing in a path to a compiled `rustc_codegen_spirv.so` (or dll)
rustc_codegen_spirv = ["dep:rustc_codegen_spirv"]
# Inclide target spec json files, allows constructing SpirvBuilder without
# explicitly passing a path to the target spec json
include-target-specs = ["dep:rustc_codegen_spirv-target-specs"]
# See `rustc_codegen_spirv/Cargo.toml` for details on these features.
use-installed-tools = ["rustc_codegen_spirv", "rustc_codegen_spirv?/use-installed-tools"]
use-compiled-tools = ["rustc_codegen_spirv", "rustc_codegen_spirv?/use-compiled-tools"]
# We add new "default" features to `use-installed-tools` and `use-compiled-tools` to keep
# backwards compat with `default-features = false, features = "use-installed-tools"` setups
use-installed-tools = ["rustc_codegen_spirv", "include-target-specs", "rustc_codegen_spirv?/use-installed-tools"]
use-compiled-tools = ["rustc_codegen_spirv", "include-target-specs", "rustc_codegen_spirv?/use-compiled-tools"]
skip-toolchain-check = ["rustc_codegen_spirv?/skip-toolchain-check"]

watch = ["dep:notify"]
clap = ["dep:clap"]

[dependencies]
# See comment in `src/lib.rs` `invoke_rustc` regarding `rustc_codegen_spirv` dep.
rustc_codegen_spirv.workspace = true
# HACK(eddyb) see `docs.rs`-related comment above for why this is optional.
rustc_codegen_spirv.optional = true

rustc_codegen_spirv-types.workspace = true
rustc_codegen_spirv = { workspace = true, optional = true }
rustc_codegen_spirv-types = { workspace = true }
rustc_codegen_spirv-target-specs = { workspace = true, features = ["dir_path"], optional = true }

memchr = "2.4"
raw-string = "0.3.5"
Expand Down
35 changes: 23 additions & 12 deletions crates/spirv-builder/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,6 @@
#![doc = include_str!("../README.md")]

mod depfile;
mod target_specs;
#[cfg(feature = "watch")]
mod watch;

Expand All @@ -91,7 +90,9 @@ use thiserror::Error;

pub use rustc_codegen_spirv_types::Capability;
pub use rustc_codegen_spirv_types::{CompileResult, ModuleResult};
pub use target_specs::TARGET_SPECS;

#[cfg(feature = "include-target-specs")]
pub use rustc_codegen_spirv_target_specs::TARGET_SPEC_DIR_PATH;

#[derive(Debug, Error)]
#[non_exhaustive]
Expand All @@ -107,11 +108,16 @@ pub enum SpirvBuilderError {
#[error("crate path '{0}' does not exist")]
CratePathDoesntExist(PathBuf),
#[error(
"Without feature `rustc_codegen_spirv`, you need to set the path of the dylib using `rustc_codegen_spirv_location(...)`"
"Without feature `rustc_codegen_spirv`, you need to set the path of the dylib with `rustc_codegen_spirv_location`"
)]
MissingRustcCodegenSpirvDylib,
#[error("`rustc_codegen_spirv_location` path '{0}' is not a file")]
RustcCodegenSpirvDylibDoesNotExist(PathBuf),
#[error(
"Without feature `include-target-specs`, instead of setting a `target`, \
you need to set the path of the target spec file of your particular target with `path_to_target_spec`"
)]
MissingTargetSpec,
#[error("build failed")]
BuildFailed,
#[error("multi-module build cannot be used with print_metadata = MetadataPrintout::Full")]
Expand Down Expand Up @@ -352,13 +358,13 @@ impl Default for ShaderCrateFeatures {
}
}

#[non_exhaustive]
#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)]
#[cfg_attr(feature = "clap", derive(clap::Parser))]
pub struct SpirvBuilder {
#[cfg_attr(feature = "clap", clap(skip))]
pub path_to_crate: Option<PathBuf>,
/// Whether to print build.rs cargo metadata (e.g. cargo:rustc-env=var=val). Defaults to [`MetadataPrintout::Full`].
/// Whether to print build.rs cargo metadata (e.g. cargo:rustc-env=var=val). Defaults to [`MetadataPrintout::None`].
/// Within build scripts, set it to [`MetadataPrintout::DependencyOnly`] or [`MetadataPrintout::Full`] to ensure the build script is rerun on code changes.
#[cfg_attr(feature = "clap", clap(skip))]
pub print_metadata: MetadataPrintout,
/// Build in release. Defaults to true.
Expand Down Expand Up @@ -975,13 +981,18 @@ fn invoke_rustc(builder: &SpirvBuilder) -> Result<PathBuf, SpirvBuilderError> {
// target_spec jsons, some later version requires them, some earlier
// version fails with them (notably our 0.9.0 release)
if toolchain_rustc_version >= Version::new(1, 76, 0) {
cargo
.arg("--target")
.arg(builder.path_to_target_spec.clone().unwrap_or_else(|| {
PathBuf::from(env!("CARGO_MANIFEST_DIR"))
.join("target-specs")
.join(format!("{}.json", target))
}));
let path_opt = builder.path_to_target_spec.clone();
let path;
#[cfg(feature = "include-target-specs")]
{
path = path_opt
.unwrap_or_else(|| PathBuf::from(format!("{TARGET_SPEC_DIR_PATH}/{target}.json")));
}
#[cfg(not(feature = "include-target-specs"))]
{
path = path_opt.ok_or(SpirvBuilderError::MissingTargetSpec)?;
}
cargo.arg("--target").arg(path);
} else {
cargo.arg("--target").arg(target);
}
Expand Down
2 changes: 1 addition & 1 deletion docs/src/writing-shader-crates.md
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ how to build SPIR-V. Here are a few things we need to mention there.

- Path to a spec of a target you're compiling for (see [platform support](./platform-support.md)).
These specs reside in a directory inside the `spirv-builder` crate and an example relative path
could look like `../rust-gpu/crates/spirv-builder/target-specs/spirv-unknown-spv1.3.json`.
could look like `../rust-gpu/crates/rustc_codegen_spirv-target-specs/target-specs/spirv-unknown-spv1.3.json`.
- Absolute path to the `rustc_codegen_spirv` dynamic library that we built above.
- Some additional options.

Expand Down
3 changes: 2 additions & 1 deletion tests/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ use-compiled-tools = ["rustc_codegen_spirv/use-compiled-tools"]

[dependencies]
compiletest = { version = "0.11.2", package = "compiletest_rs" }
rustc_codegen_spirv.workspace = true
rustc_codegen_spirv = { workspace = true }
rustc_codegen_spirv-target-specs = { workspace = true, features = ["dir_path"] }
clap = { version = "4", features = ["derive"] }
itertools = "0.10.5"
6 changes: 2 additions & 4 deletions tests/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use clap::Parser;
use itertools::Itertools as _;
use rustc_codegen_spirv_target_specs::TARGET_SPEC_DIR_PATH;
use std::{
env, io,
path::{Path, PathBuf},
Expand Down Expand Up @@ -30,10 +31,7 @@ impl Opt {
const SPIRV_TARGET_PREFIX: &str = "spirv-unknown-";

fn target_spec_json(target: &str) -> String {
format!(
"{}/../crates/spirv-builder/target-specs/{target}.json",
env!("CARGO_MANIFEST_DIR")
)
format!("{TARGET_SPEC_DIR_PATH}/{target}.json")
}

#[derive(Copy, Clone)]
Expand Down