diff --git a/Cargo.lock b/Cargo.lock index 4bf24277..7efe3c4c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -102,11 +102,9 @@ name = "cargo-gpu" version = "0.1.0" dependencies = [ "anyhow", - "cargo-util-schemas", + "cargo-gpu-install", "cargo_metadata", "clap", - "crossterm", - "directories", "dunce", "env_logger", "log", @@ -114,6 +112,21 @@ dependencies = [ "semver", "serde", "serde_json", + "test-log", +] + +[[package]] +name = "cargo-gpu-install" +version = "0.1.0" +dependencies = [ + "anyhow", + "cargo-util-schemas", + "cargo_metadata", + "clap", + "crossterm", + "directories", + "log", + "serde", "spirv-builder", "tempfile", "test-log", @@ -212,15 +225,6 @@ version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990" -[[package]] -name = "convert_case" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb402b8d4c85569410425650ce3eddc7d698ed96d39a73f941b08fb63082f1e7" -dependencies = [ - "unicode-segmentation", -] - [[package]] name = "crossterm" version = "0.29.0" @@ -229,7 +233,6 @@ checksum = "d8b9f2e4c67f833b660cdb0a3523065869fb35570177239812ed4c905aeff87b" dependencies = [ "bitflags 2.9.0", "crossterm_winapi", - "derive_more", "document-features", "mio", "parking_lot", @@ -314,27 +317,6 @@ dependencies = [ "syn", ] -[[package]] -name = "derive_more" -version = "2.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "093242cf7570c207c83073cf82f79706fe7b8317e98620a47d5be7c3d8497678" -dependencies = [ - "derive_more-impl", -] - -[[package]] -name = "derive_more-impl" -version = "2.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bda628edc44c4bb645fbe0f758797143e4e07926f7ebf4e9bdfbd3d2ce621df3" -dependencies = [ - "convert_case", - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "directories" version = "6.0.0" @@ -1164,9 +1146,9 @@ dependencies = [ [[package]] name = "signal-hook" -version = "0.3.17" +version = "0.3.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8621587d4798caf8eb44879d42e56b9a93ea5dcd315a6487c357130095b62801" +checksum = "d881a16cf4426aa584979d30bd82cb33429027e42122b169753d6ef1085ed6e2" dependencies = [ "libc", "signal-hook-registry", @@ -1174,9 +1156,9 @@ dependencies = [ [[package]] name = "signal-hook-mio" -version = "0.2.4" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34db1a06d485c9142248b7a054f034b349b212551f3dfd19c94d45a754a217cd" +checksum = "b75a19a7a740b25bc7944bdee6172368f988763b744e3d4dfe753f6b4ece40cc" dependencies = [ "libc", "mio", @@ -1185,9 +1167,9 @@ dependencies = [ [[package]] name = "signal-hook-registry" -version = "1.4.5" +version = "1.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9203b8055f63a2a00e2f593bb0510367fe707d7ff1e5c872de2f537b339e5410" +checksum = "7664a098b8e616bdfcc2dc0e9ac44eb231eedf41db4e9fe95d8d32ec728dedad" dependencies = [ "libc", ] @@ -1475,12 +1457,6 @@ version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" -[[package]] -name = "unicode-segmentation" -version = "1.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" - [[package]] name = "unicode-xid" version = "0.2.6" diff --git a/Cargo.toml b/Cargo.toml index 7c66d0a9..3e93182d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,7 @@ [workspace] members = [ "crates/cargo-gpu", + "crates/cargo-gpu-install", "crates/xtask", ] @@ -14,11 +15,20 @@ exclude = [ resolver = "2" +[workspace.package] +version = "0.1.0" +edition = "2021" +repository = "https://github.com/Rust-GPU/cargo-gpu" +readme = "./README.md" +keywords = ["gpu", "compiler", "rust-gpu"] +license = "MIT OR Apache-2.0" + [workspace.dependencies] spirv-builder = { git = "https://github.com/Rust-GPU/rust-gpu", rev = "823b0c275e3eb8ab44ada5a6d989bdb57e8f9409", default-features = false } +cargo-gpu-install = { path = "./crates/cargo-gpu-install" } anyhow = "1.0.98" clap = { version = "4.5.41", features = ["derive"] } -crossterm = "0.29.0" +crossterm = { version = "0.29.0", default-features = false, features = ["events", "windows"] } directories = "6.0.0" env_logger = "0.11.8" log = "0.4" diff --git a/crates/cargo-gpu-install/Cargo.toml b/crates/cargo-gpu-install/Cargo.toml new file mode 100644 index 00000000..8a914c70 --- /dev/null +++ b/crates/cargo-gpu-install/Cargo.toml @@ -0,0 +1,34 @@ +[package] +name = "cargo-gpu-install" +version.workspace = true +edition.workspace = true +description = "Install rust-gpu and it's required toolchain automatically" +repository.workspace = true +readme.workspace = true +keywords.workspace = true +license.workspace = true + +[features] +clap = ["dep:clap", "spirv-builder/clap"] +watch = ["spirv-builder/watch"] +test = ["dep:tempfile"] +tty = ["dep:crossterm"] + +[dependencies] +cargo_metadata.workspace = true +anyhow.workspace = true +spirv-builder.workspace = true +clap = { workspace = true, optional = true } +directories.workspace = true +log.workspace = true +serde.workspace = true +crossterm = { workspace = true, optional = true } +tempfile = { workspace = true, optional = true } + +[dev-dependencies] +test-log.workspace = true +cargo_metadata = { workspace = true, features = ["builder"] } +cargo-util-schemas = "0.8.2" + +[lints] +workspace = true diff --git a/crates/cargo-gpu-install/README.md b/crates/cargo-gpu-install/README.md new file mode 100644 index 00000000..5068029c --- /dev/null +++ b/crates/cargo-gpu-install/README.md @@ -0,0 +1,43 @@ +# cargo-gpu-install + +`cargo-gpu-install` is the install action of `cargo-gpu`, separated into its own crate. It's intended to be used +by build scripts and other binaries that need automated installation of rust-gpu and it's required toolchain, +without having to pull all the other cli dependencies of the full `cargo-gpu` (like clap). + +## Example + +This is an example build script meant to be placed in your "main" std crate, to build a secondary no-std "shader" crate. +But you can just as well use this in your executable directly, with some minor adjustments. +```rust,no_run +# use std::path::PathBuf; +# use cargo_gpu_install::install::Install; +# use cargo_gpu_install::spirv_builder::SpirvMetadata; + +pub fn main() -> Result<(), Box> { + // path to your shader crate + let shader_crate = PathBuf::from("./shaders"); + + // install the toolchain and build the `rustc_codegen_spirv` codegen backend with it + let backend = Install::from_shader_crate(shader_crate.clone()).run()?; + + // build the shader crate + let mut builder = backend.to_spirv_builder(shader_crate, "spirv-unknown-vulkan1.2"); + // set to true when you're in a build script, false when outside one + builder.build_script.defaults = true; + // enable debug information in the shaders + builder.spirv_metadata = SpirvMetadata::Full; + let spv_result = builder.build()?; + let path_to_spv = spv_result.module.unwrap_single(); + + // emit path to the artifact into env var, use it anywhere in your crate like: + // > include_str!(env!("MY_SHADER_PATH")) + println!( + "cargo::rustc-env=MY_SHADER_PATH={}", + path_to_spv.display() + ); + + // you could also generate some rust source code into the `std::env::var("OUT_DIR")` dir + // and use `include!(concat!(env!("OUT_DIR"), "/shader_symbols.rs"));` to include it + Ok(()) +} +``` diff --git a/crates/cargo-gpu/src/install.rs b/crates/cargo-gpu-install/src/install.rs similarity index 94% rename from crates/cargo-gpu/src/install.rs rename to crates/cargo-gpu-install/src/install.rs index c9ea0ece..0de94036 100644 --- a/crates/cargo-gpu/src/install.rs +++ b/crates/cargo-gpu-install/src/install.rs @@ -54,19 +54,23 @@ impl InstalledBackend { clippy::struct_excessive_bools, reason = "cmdline args have many bools" )] -#[derive(clap::Parser, Debug, Clone, serde::Deserialize, serde::Serialize)] +#[derive(Debug, Clone, serde::Deserialize, serde::Serialize)] +#[cfg_attr(feature = "clap", derive(clap::Parser))] #[non_exhaustive] pub struct Install { /// Cargo target to compile. /// /// Conflicts with `--shader-crate`. - #[clap(short, long, conflicts_with("shader_crate"))] + #[cfg_attr(feature = "clap", clap(short, long, conflicts_with("shader_crate")))] pub package: Option, /// Directory containing the shader crate to compile. /// /// Conflicts with `--package` or `-p`. - #[clap(long, default_value = "./", conflicts_with("package"))] + #[cfg_attr( + feature = "clap", + clap(long, default_value = "./", conflicts_with("package")) + )] pub shader_crate: PathBuf, #[expect( @@ -75,7 +79,7 @@ pub struct Install { )] /// Source of `spirv-builder` dependency /// Eg: "https://github.com/Rust-GPU/rust-gpu" - #[clap(long)] + #[cfg_attr(feature = "clap", clap(long))] pub spirv_builder_source: Option, /// Version of `spirv-builder` dependency. @@ -83,22 +87,22 @@ pub struct Install { /// version such as "0.9.0". /// * If `--spirv-builder-source` is set, then this is assumed to be a Git "commitsh", such /// as a Git commit hash or a Git tag, therefore anything that `git checkout` can resolve. - #[clap(long, verbatim_doc_comment)] + #[cfg_attr(feature = "clap", clap(long, verbatim_doc_comment))] pub spirv_builder_version: Option, /// Force `rustc_codegen_spirv` to be rebuilt. - #[clap(long)] + #[cfg_attr(feature = "clap", clap(long))] pub rebuild_codegen: bool, /// Assume "yes" to "Install Rust toolchain: [y/n]" prompt. /// /// Defaults to `false` in cli, `true` in [`Default`] - #[clap(long, action)] + #[cfg_attr(feature = "clap", clap(long, action))] pub auto_install_rust_toolchain: bool, /// Clear target dir of `rustc_codegen_spirv` build after a successful build, saves about /// 200MiB of disk space. - #[clap(long = "no-clear-target", default_value = "true", action = clap::ArgAction::SetFalse)] + #[cfg_attr(feature = "clap", clap(long = "no-clear-target", default_value = "true", action = clap::ArgAction::SetFalse))] pub clear_target: bool, /// There is a tricky situation where a shader crate that depends on workspace config can have @@ -122,7 +126,7 @@ pub struct Install { /// way source URLs are encoded. See these PRs for more details: /// * /// * - #[clap(long, action, verbatim_doc_comment)] + #[cfg_attr(feature = "clap", clap(long, action, verbatim_doc_comment))] pub force_overwrite_lockfiles_v4_to_v3: bool, } diff --git a/crates/cargo-gpu/src/install_toolchain.rs b/crates/cargo-gpu-install/src/install_toolchain.rs similarity index 88% rename from crates/cargo-gpu/src/install_toolchain.rs rename to crates/cargo-gpu-install/src/install_toolchain.rs index 98d35d59..300ddb83 100644 --- a/crates/cargo-gpu/src/install_toolchain.rs +++ b/crates/cargo-gpu-install/src/install_toolchain.rs @@ -1,6 +1,7 @@ //! toolchain installation logic use anyhow::Context as _; +#[cfg(feature = "tty")] use crossterm::tty::IsTty as _; use crate::user_output; @@ -98,6 +99,20 @@ pub fn ensure_toolchain_and_components_exist( Ok(()) } +#[cfg(not(feature = "tty"))] +/// Prompt user if they want to install a new Rust toolchain. +fn get_consent_for_toolchain_install( + _prompt: &str, + skip_toolchain_install_consent: bool, +) -> anyhow::Result<()> { + if skip_toolchain_install_consent { + Ok(()) + } else { + no_tty() + } +} + +#[cfg(feature = "tty")] /// Prompt user if they want to install a new Rust toolchain. fn get_consent_for_toolchain_install( prompt: &str, @@ -108,10 +123,7 @@ fn get_consent_for_toolchain_install( } if !std::io::stdout().is_tty() { - user_output!("No TTY detected so can't ask for consent to install Rust toolchain."); - log::error!("Attempted to ask for consent when there's no TTY"); - #[expect(clippy::exit, reason = "can't ask for user consent if there's no TTY")] - std::process::exit(1); + no_tty() } log::debug!("asking for consent to install the required toolchain"); @@ -143,3 +155,10 @@ fn get_consent_for_toolchain_install( std::process::exit(0); } } + +fn no_tty() -> ! { + user_output!("No TTY detected so can't ask for consent to install Rust toolchain."); + log::error!("Attempted to ask for consent when there's no TTY"); + #[expect(clippy::exit, reason = "can't ask for user consent if there's no TTY")] + std::process::exit(1); +} diff --git a/crates/cargo-gpu-install/src/lib.rs b/crates/cargo-gpu-install/src/lib.rs new file mode 100644 index 00000000..d7b22101 --- /dev/null +++ b/crates/cargo-gpu-install/src/lib.rs @@ -0,0 +1,77 @@ +#![expect(clippy::pub_use, reason = "pub use for build scripts")] +#![expect( + missing_docs, + clippy::missing_docs_in_private_items, + reason = "crate docs are cfg'ed out" +)] +#![cfg_attr(doc, doc = include_str!("../README.md"))] + +pub mod install; +mod install_toolchain; +pub mod spirv_source; +pub mod test; + +pub use spirv_builder; + +/// Central function to write to the user. +#[macro_export] +#[cfg(feature = "tty")] +macro_rules! user_output { + ($($args: tt)*) => { { + #[allow( + clippy::allow_attributes, + clippy::useless_attribute, + unused_imports, + reason = "`std::io::Write` is only sometimes called??" + )] + use std::io::Write as _; + + #[expect( + clippy::non_ascii_literal, + reason = "CRAB GOOD. CRAB IMPORTANT." + )] + { + print!("🦀 "); + } + print!($($args)*); + std::io::stdout().flush().unwrap(); + } } +} + +/// Central function to write to the user. +#[macro_export] +#[cfg(not(feature = "tty"))] +macro_rules! user_output { + ($($args: tt)*) => {{}}; +} + +/// The central cache directory of cargo gpu +/// +/// # Errors +/// may fail if we can't find the user home directory +#[inline] +#[cfg(not(any(feature = "test", test)))] +#[expect(clippy::cfg_not_test, reason = "tests use different cache_dir")] +pub fn cache_dir() -> anyhow::Result { + use anyhow::Context as _; + Ok(directories::BaseDirs::new() + .with_context(|| "could not find the user home directory")? + .cache_dir() + .join("rust-gpu")) +} + +#[cfg(any(feature = "test", test))] +pub use test::test_cache_dir as cache_dir; + +/// Returns a string suitable to use as a directory. +/// +/// Created from the spirv-builder source dep and the rustc channel. +fn to_dirname(text: &str) -> String { + text.replace( + [std::path::MAIN_SEPARATOR, '\\', '/', '.', ':', '@', '='], + "_", + ) + .split(['{', '}', ' ', '\n', '"', '\'']) + .collect::>() + .concat() +} diff --git a/crates/cargo-gpu/src/spirv_source.rs b/crates/cargo-gpu-install/src/spirv_source.rs similarity index 96% rename from crates/cargo-gpu/src/spirv_source.rs rename to crates/cargo-gpu-install/src/spirv_source.rs index 1775a997..d0ae054f 100644 --- a/crates/cargo-gpu/src/spirv_source.rs +++ b/crates/cargo-gpu-install/src/spirv_source.rs @@ -22,6 +22,7 @@ use std::path::{Path, PathBuf}; /// - a repo of "https://github.com/Rust-GPU/rust-gpu.git" /// - a revision of "abc213" /// * a local Path +#[non_exhaustive] #[derive(Eq, PartialEq, Clone, Debug)] pub enum SpirvSource { /// If the shader specifies a simple version like `spirv-std = "0.9.0"` then the source of @@ -69,6 +70,9 @@ impl core::fmt::Display for SpirvSource { impl SpirvSource { /// Figures out which source of `rust-gpu` to use + /// + /// # Errors + /// Crate may not depend on `spirv-std` or is otherwise malformed pub fn new( shader_crate_path: &Path, maybe_rust_gpu_source: Option<&str>, @@ -95,6 +99,9 @@ impl SpirvSource { } /// Look into the shader crate to get the version of `rust-gpu` it's using. + /// + /// # 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 { let crate_metadata = query_metadata(shader_crate_path)?; let spirv_std_package = crate_metadata.find_package("spirv-std")?; @@ -110,6 +117,9 @@ impl SpirvSource { /// Convert the `SpirvSource` to a cache directory in which we can build it. /// It needs to be dynamically created because an end-user might want to swap out the source, /// maybe using their own fork for example. + /// + /// # Errors + /// [`crate::cache_dir`] may fail pub fn install_dir(&self) -> anyhow::Result { match self { Self::Path { @@ -123,6 +133,7 @@ impl SpirvSource { } /// Returns true if self is a Path + #[must_use] pub const fn is_path(&self) -> bool { matches!(self, Self::Path { .. }) } @@ -182,6 +193,9 @@ impl SpirvSource { } /// get the Package metadata from some crate +/// +/// # Errors +/// metadata query may fail pub fn query_metadata(crate_path: &Path) -> anyhow::Result { log::debug!("Running `cargo metadata` on `{}`", crate_path.display()); let metadata = MetadataCommand::new() @@ -197,6 +211,9 @@ pub fn query_metadata(crate_path: &Path) -> anyhow::Result { /// implements [`Self::find_package`] pub trait FindPackage { /// 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>; } @@ -219,6 +236,9 @@ impl FindPackage for Metadata { } /// Parse the `rust-toolchain.toml` in the working tree of the checked-out version of the `rust-gpu` repo. +/// +/// # Errors +/// parsing may fail pub fn get_channel_from_rustc_codegen_spirv_build_script( rustc_codegen_spirv_package: &Package, ) -> anyhow::Result { diff --git a/crates/cargo-gpu/src/test.rs b/crates/cargo-gpu-install/src/test.rs similarity index 99% rename from crates/cargo-gpu/src/test.rs rename to crates/cargo-gpu-install/src/test.rs index 4fb6a8da..8cdc5cf8 100644 --- a/crates/cargo-gpu/src/test.rs +++ b/crates/cargo-gpu-install/src/test.rs @@ -1,5 +1,5 @@ //! utilities for tests -#![cfg(test)] +#![cfg(any(feature = "test", test))] use anyhow::Context; use std::cell::RefCell; diff --git a/crates/cargo-gpu/Cargo.toml b/crates/cargo-gpu/Cargo.toml index 81c8a87d..951e8845 100644 --- a/crates/cargo-gpu/Cargo.toml +++ b/crates/cargo-gpu/Cargo.toml @@ -1,35 +1,32 @@ [package] name = "cargo-gpu" -version = "0.1.0" -edition = "2021" +version.workspace = true +edition.workspace = true description = "Generates shader .spv files from rust-gpu shader crates" -repository = "https://github.com/Rust-GPU/cargo-gpu" -readme = "../../README.md" -keywords = ["gpu", "compiler", "rust-gpu"] -license = "MIT OR Apache-2.0" +repository.workspace = true +readme.workspace = true +keywords.workspace = true +license.workspace = true default-run = "cargo-gpu" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] cargo_metadata.workspace = true anyhow.workspace = true -spirv-builder = { workspace = true, features = ["clap", "watch"] } +cargo-gpu-install = { workspace = true, features = ["clap", "watch", "tty"] } clap.workspace = true -directories.workspace = true env_logger.workspace = true log.workspace = true relative-path.workspace = true serde.workspace = true serde_json.workspace = true -crossterm.workspace = true semver.workspace = true dunce.workspace = true [dev-dependencies] -tempfile.workspace = true +cargo-gpu-install = { workspace = true, features = ["test"] } test-log.workspace = true cargo_metadata = { workspace = true, features = ["builder"] } -cargo-util-schemas = "0.8.2" [lints] workspace = true diff --git a/crates/cargo-gpu/src/build.rs b/crates/cargo-gpu/src/build.rs index e8e620cb..22a5a732 100644 --- a/crates/cargo-gpu/src/build.rs +++ b/crates/cargo-gpu/src/build.rs @@ -5,8 +5,8 @@ use crate::install::Install; use crate::linkage::Linkage; use crate::lockfile::LockfileMismatchHandler; +use crate::spirv_builder::{CompileResult, ModuleResult, SpirvBuilder, SpirvBuilderError}; use anyhow::Context as _; -use spirv_builder::{CompileResult, ModuleResult, SpirvBuilder, SpirvBuilderError}; use std::io::Write as _; use std::path::PathBuf; diff --git a/crates/cargo-gpu/src/config.rs b/crates/cargo-gpu/src/config.rs index 3c3d6677..5fe2adb1 100644 --- a/crates/cargo-gpu/src/config.rs +++ b/crates/cargo-gpu/src/config.rs @@ -89,6 +89,7 @@ impl Config { mod test { use super::*; + use crate::spirv_builder::Capability; use crate::test::TestEnv; use std::io::Write as _; @@ -223,10 +224,7 @@ mod test { .unwrap(); assert_eq!( args.build.spirv_builder.capabilities, - vec![ - spirv_builder::Capability::AtomicStorage, - spirv_builder::Capability::Matrix - ] + vec![Capability::AtomicStorage, Capability::Matrix] ); } diff --git a/crates/cargo-gpu/src/lib.rs b/crates/cargo-gpu/src/lib.rs index d4822781..6b345b59 100644 --- a/crates/cargo-gpu/src/lib.rs +++ b/crates/cargo-gpu/src/lib.rs @@ -1,4 +1,4 @@ -#![expect(clippy::pub_use, reason = "pub use for build scripts")] +#![expect(clippy::pub_use, reason = "reexports from cargo_gpu_install crate")] //! Rust GPU shader crate builder. //! @@ -50,62 +50,31 @@ //! conduct other post-processing, like converting the `spv` files into `wgsl` files, //! for example. -use crate::dump_usage::dump_full_usage_for_readme; -use build::Build; -use show::Show; +#[cfg(test)] +pub use cargo_gpu_install::test; +pub use cargo_gpu_install::{cache_dir, install, spirv_builder, spirv_source, user_output}; +pub use metadata::MetadataCache; mod build; mod config; mod dump_usage; -mod install; -mod install_toolchain; mod linkage; mod lockfile; mod metadata; mod show; -mod spirv_source; -mod test; - -pub use install::*; -pub use metadata::MetadataCache; -pub use spirv_builder; - -/// Central function to write to the user. -#[macro_export] -macro_rules! user_output { - ($($args: tt)*) => { { - #[allow( - clippy::allow_attributes, - clippy::useless_attribute, - unused_imports, - reason = "`std::io::Write` is only sometimes called??" - )] - use std::io::Write as _; - - #[expect( - clippy::non_ascii_literal, - reason = "CRAB GOOD. CRAB IMPORTANT." - )] - { - print!("🦀 "); - } - print!($($args)*); - std::io::stdout().flush().unwrap(); - } } -} /// All of the available subcommands for `cargo gpu` #[derive(clap::Subcommand)] #[non_exhaustive] pub enum Command { /// Install rust-gpu compiler artifacts. - Install(Box), + Install(Box), /// Compile a shader crate to SPIR-V. - Build(Box), + Build(Box), /// Show some useful values. - Show(Show), + Show(show::Show), /// A hidden command that can be used to recursively print out all the subcommand help messages: /// `cargo gpu dump-usage` @@ -157,7 +126,7 @@ impl Command { command.run()?; } Self::Show(show) => show.run()?, - Self::DumpUsage => dump_full_usage_for_readme()?, + Self::DumpUsage => dump_usage::dump_full_usage_for_readme()?, } Ok(()) @@ -173,34 +142,3 @@ pub struct Cli { #[clap(subcommand)] pub command: Command, } - -/// The central cache directory of cargo gpu -/// -/// # Errors -/// may fail if we can't find the user home directory -#[inline] -#[cfg(not(test))] -#[expect(clippy::cfg_not_test, reason = "tests use different cache_dir")] -pub fn cache_dir() -> anyhow::Result { - use anyhow::Context as _; - Ok(directories::BaseDirs::new() - .with_context(|| "could not find the user home directory")? - .cache_dir() - .join("rust-gpu")) -} - -#[cfg(test)] -pub use test::test_cache_dir as cache_dir; - -/// Returns a string suitable to use as a directory. -/// -/// Created from the spirv-builder source dep and the rustc channel. -fn to_dirname(text: &str) -> String { - text.replace( - [std::path::MAIN_SEPARATOR, '\\', '/', '.', ':', '@', '='], - "_", - ) - .split(['{', '}', ' ', '\n', '"', '\'']) - .collect::>() - .concat() -} diff --git a/crates/cargo-gpu/src/lockfile.rs b/crates/cargo-gpu/src/lockfile.rs index bce1487a..89aaad6f 100644 --- a/crates/cargo-gpu/src/lockfile.rs +++ b/crates/cargo-gpu/src/lockfile.rs @@ -2,9 +2,9 @@ //! v0.9.0 uses an old toolchain requiring v3 and will refuse to build with a v4 lockfile being //! present. This module takes care of warning the user and potentially downgrading the lockfile. +use crate::spirv_builder::query_rustc_version; use anyhow::Context as _; use semver::Version; -use spirv_builder::query_rustc_version; use std::io::Write as _; /// `Cargo.lock` manifest version 4 became the default in Rust 1.83.0. Conflicting manifest diff --git a/crates/cargo-gpu/src/show.rs b/crates/cargo-gpu/src/show.rs index 1e318c48..491550cd 100644 --- a/crates/cargo-gpu/src/show.rs +++ b/crates/cargo-gpu/src/show.rs @@ -1,6 +1,7 @@ //! Display various information about `cargo gpu`, eg its cache directory. use crate::cache_dir; +use crate::spirv_builder::Capability; use crate::spirv_source::SpirvSource; /// Show the computed source of the spirv-std dependency. @@ -69,11 +70,11 @@ impl Show { } /// Iterator over all `Capability` variants. - fn capability_variants_iter() -> impl Iterator { + fn capability_variants_iter() -> impl Iterator { // Since spirv::Capability is repr(u32) we can iterate over // u32s until some maximum #[expect(clippy::as_conversions, reason = "We know all variants are repr(u32)")] - let last_capability = spirv_builder::Capability::CacheControlsINTEL as u32; - (0..=last_capability).filter_map(spirv_builder::Capability::from_u32) + let last_capability = Capability::CacheControlsINTEL as u32; + (0..=last_capability).filter_map(Capability::from_u32) } }