Skip to content
Open
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
14 changes: 8 additions & 6 deletions crates/cargo-gpu-install/src/install.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
//! Install a dedicated per-shader crate that has the `rust-gpu` compiler in it.

use crate::spirv_source::{
FindPackage as _, get_channel_from_rustc_codegen_spirv_build_script, query_metadata,
};
use crate::spirv_source::{CrateMetadata, get_channel_from_rustc_codegen_spirv_build_script};
use crate::{cache_dir, spirv_source::SpirvSource};
use anyhow::Context as _;
use spirv_builder::SpirvBuilder;
Expand Down Expand Up @@ -238,8 +236,9 @@ package = "rustc_codegen_spirv"
format!("could not create cache directory '{}'", cache_dir.display())
})?;

let metadata = CrateMetadata::query(self.shader_crate.clone())?;
let source = SpirvSource::new(
&self.shader_crate,
&metadata,
self.spirv_builder_source.as_deref(),
self.spirv_builder_version.as_deref(),
)?;
Expand All @@ -251,8 +250,11 @@ package = "rustc_codegen_spirv"
std::env::consts::DLL_SUFFIX
);

#[allow(clippy::print_stdout)]
if self.build_script {
#[allow(clippy::print_stdout)]
let root = metadata.workspace_root.as_path();
println!("cargo:rerun-if-changed={root}/Cargo.lock");

if let SpirvSource::Path {
rust_gpu_repo_root, ..
} = &source
Expand Down Expand Up @@ -289,7 +291,7 @@ package = "rustc_codegen_spirv"

// TODO cache toolchain channel in a file?
log::debug!("resolving toolchain version to use");
let dummy_metadata = query_metadata(&install_dir)
let dummy_metadata = CrateMetadata::query(install_dir.clone())
.context("resolving toolchain version: get `rustc_codegen_spirv_dummy` metadata")?;
let rustc_codegen_spirv = dummy_metadata.find_package("rustc_codegen_spirv").context(
"resolving toolchain version: expected a dependency on `rustc_codegen_spirv`",
Expand Down
74 changes: 45 additions & 29 deletions crates/cargo-gpu-install/src/spirv_source.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use cargo_metadata::camino::{Utf8Path, Utf8PathBuf};
use cargo_metadata::semver::Version;
use cargo_metadata::{Metadata, MetadataCommand, Package};
use std::fs;
use std::ops::Deref;
use std::path::{Path, PathBuf};

#[expect(
Expand Down Expand Up @@ -75,7 +76,7 @@ impl SpirvSource {
/// # Errors
/// Crate may not depend on `spirv-std` or is otherwise malformed
pub fn new(
shader_crate_path: &Path,
shader_crate: &CrateMetadata,
maybe_rust_gpu_source: Option<&str>,
maybe_rust_gpu_version: Option<&str>,
) -> anyhow::Result<Self> {
Expand All @@ -89,10 +90,10 @@ impl SpirvSource {
Self::CratesIO(Version::parse(rust_gpu_version)?)
}
} else {
Self::get_rust_gpu_deps_from_shader(shader_crate_path).with_context(|| {
Self::get_rust_gpu_deps_from_shader(shader_crate).with_context(|| {
format!(
"get spirv-std dependency from shader crate '{}'",
shader_crate_path.display()
shader_crate.path().display()
)
})?
};
Expand All @@ -103,14 +104,13 @@ impl SpirvSource {
///
/// # Errors
/// Crate may not depend on `spirv-std` or is otherwise malformed
pub fn get_rust_gpu_deps_from_shader(shader_crate_path: &Path) -> anyhow::Result<Self> {
let crate_metadata = query_metadata(shader_crate_path)?;
pub fn get_rust_gpu_deps_from_shader(crate_metadata: &CrateMetadata) -> anyhow::Result<Self> {
let spirv_std_package = crate_metadata.find_package("spirv-std")?;
let spirv_source = Self::parse_spirv_std_source_and_version(spirv_std_package)?;
log::debug!(
"Parsed `SpirvSource` from crate `{}`: \
{spirv_source:?}",
shader_crate_path.display(),
crate_metadata.path().display(),
);
Ok(spirv_source)
}
Expand Down Expand Up @@ -193,33 +193,39 @@ impl SpirvSource {
}
}

/// get the Package metadata from some crate
///
/// # Errors
/// metadata query may fail
pub fn query_metadata(crate_path: &Path) -> anyhow::Result<Metadata> {
log::debug!("Running `cargo metadata` on `{}`", crate_path.display());
let metadata = MetadataCommand::new()
.current_dir(
&crate_path
.canonicalize()
.context("could not get absolute path to shader crate")?,
)
.exec()?;
Ok(metadata)
/// [`cargo_metadata::Metadata`] combined with the path to the crate being queried
pub struct CrateMetadata {
path: PathBuf,
metadata: Metadata,
}

/// implements [`Self::find_package`]
pub trait FindPackage {
impl CrateMetadata {
/// get the Package metadata from some crate
///
/// # Errors
/// metadata query may fail
pub fn query(path: PathBuf) -> anyhow::Result<Self> {
log::debug!("Running `cargo metadata` on `{}`", path.display());
let metadata = MetadataCommand::new()
.current_dir(
&path
.canonicalize()
.context("could not get absolute path to shader crate")?,
)
.exec()?;
Ok(Self { path, metadata })
}

/// Path to the crate that was queried
pub fn path(&self) -> &Path {
self.path.as_path()
}

/// Search for a package or return a nice error
///
/// # Errors
/// package may not be found or crate may be malformed
fn find_package(&self, crate_name: &str) -> anyhow::Result<&Package>;
}

impl FindPackage for Metadata {
fn find_package(&self, crate_name: &str) -> anyhow::Result<&Package> {
pub fn find_package(&self, crate_name: &str) -> anyhow::Result<&Package> {
if let Some(package) = self
.packages
.iter()
Expand All @@ -236,6 +242,14 @@ impl FindPackage for Metadata {
}
}

impl Deref for CrateMetadata {
type Target = Metadata;

fn deref(&self) -> &Self::Target {
&self.metadata
}
}

/// Parse the `rust-toolchain.toml` in the working tree of the checked-out version of the `rust-gpu` repo.
///
/// # Errors
Expand Down Expand Up @@ -273,7 +287,8 @@ mod test {
#[test_log::test]
fn parsing_spirv_std_dep_for_shader_template() {
let shader_template_path = crate::test::shader_crate_template_path();
let source = SpirvSource::get_rust_gpu_deps_from_shader(&shader_template_path).unwrap();
let metadata = CrateMetadata::query(shader_template_path).unwrap();
let source = SpirvSource::get_rust_gpu_deps_from_shader(&metadata).unwrap();
expect![[r#"
Git {
url: "https://github.com/Rust-GPU/rust-gpu",
Expand All @@ -286,7 +301,8 @@ mod test {
fn cached_checkout_dir_sanity() {
let _env = TestEnv::new();
let shader_template_path = crate::test::shader_crate_template_path();
let source = SpirvSource::get_rust_gpu_deps_from_shader(&shader_template_path).unwrap();
let metadata = CrateMetadata::query(shader_template_path).unwrap();
let source = SpirvSource::get_rust_gpu_deps_from_shader(&metadata).unwrap();
let dir = source.install_dir().unwrap();
let name = dir
.file_name()
Expand Down
4 changes: 3 additions & 1 deletion crates/cargo-gpu/src/show.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
use crate::cache_dir;
use crate::spirv_builder::Capability;
use crate::spirv_source::SpirvSource;
use cargo_gpu_install::spirv_source::CrateMetadata;

/// Show the computed source of the spirv-std dependency.
#[derive(Clone, Debug, clap::Parser)]
Expand Down Expand Up @@ -48,7 +49,8 @@ impl Show {
println!("{}\n", cache_dir()?.display());
}
Info::SpirvSource(SpirvSourceDep { shader_crate }) => {
let rust_gpu_source = SpirvSource::get_rust_gpu_deps_from_shader(shader_crate)?;
let metadata = CrateMetadata::query(shader_crate.clone())?;
let rust_gpu_source = SpirvSource::get_rust_gpu_deps_from_shader(&metadata)?;
println!("{rust_gpu_source}\n");
}
Info::Commitsh => {
Expand Down
Loading