From 87de5da3c7fe9da3036a094bc08409b553cc66da Mon Sep 17 00:00:00 2001 From: Thomas Buckley-Houston Date: Tue, 17 Dec 2024 13:11:46 +0100 Subject: [PATCH 01/10] Rename Spirv to SpirvCLI --- crates/cargo-gpu/src/install.rs | 2 +- crates/cargo-gpu/src/main.rs | 6 +++--- crates/cargo-gpu/src/{spirv.rs => spirv_cli.rs} | 0 3 files changed, 4 insertions(+), 4 deletions(-) rename crates/cargo-gpu/src/{spirv.rs => spirv_cli.rs} (100%) diff --git a/crates/cargo-gpu/src/install.rs b/crates/cargo-gpu/src/install.rs index 0e31f2b..68d4f4c 100644 --- a/crates/cargo-gpu/src/install.rs +++ b/crates/cargo-gpu/src/install.rs @@ -1,7 +1,7 @@ //! Install a dedicated per-shader crate that has the `rust-gpu` compiler in it. use std::io::Write as _; -use crate::{cache_dir, spirv::Spirv, target_spec_dir}; +use crate::{cache_dir, spirv_cli::Spirv, target_spec_dir}; /// These are the files needed to create the dedicated, per-shader `rust-gpu` builder create. const SPIRV_BUILDER_FILES: &[(&str, &str)] = &[ diff --git a/crates/cargo-gpu/src/main.rs b/crates/cargo-gpu/src/main.rs index cb14ee6..542b847 100644 --- a/crates/cargo-gpu/src/main.rs +++ b/crates/cargo-gpu/src/main.rs @@ -59,7 +59,7 @@ use toml::Toml; mod build; mod install; mod show; -mod spirv; +mod spirv_cli; mod toml; fn main() { @@ -173,14 +173,14 @@ fn write_help(buffer: &mut impl std::io::Write, cmd: &mut clap::Command, _depth: #[cfg(test)] mod test { - use spirv::Spirv; + use spirv_cli::Spirv as SpirvCLI; use super::*; #[test] fn cached_checkout_dir_sanity() { // Test that - let spirv = Spirv::default(); + let spirv = SpirvCLI::default(); let dir = spirv.cached_checkout_path(); let name = dir .file_name() diff --git a/crates/cargo-gpu/src/spirv.rs b/crates/cargo-gpu/src/spirv_cli.rs similarity index 100% rename from crates/cargo-gpu/src/spirv.rs rename to crates/cargo-gpu/src/spirv_cli.rs From 79cb0def6f244fd2912b7041d44a54c0323419ae Mon Sep 17 00:00:00 2001 From: Thomas Buckley-Houston Date: Tue, 17 Dec 2024 21:17:28 +0100 Subject: [PATCH 02/10] Use shader's Cargo.toml for rust-gpu version/toolchain We can still override the version and toolchain with CLI args. This commit just changes the defaults. I feel like there could be a lot of edge cases for this implementation. So I consider it more of a first draft. Notable changes: * `Spirv` renamed to `SpirvCli`. * New `impl SpirvSource` that does all the shader crate querying. * CLI args change: `--spirv-builder` is now split into `--spirv-builder-source` and `--spirv-builder-version`. * `--shader-crate` now lives on the `install` subcommand, which because it is inherited by `build` (where it was originally), means it doesn't make much of a difference. * The full build test now has a teardown function making it idempotent. * Cache folder structure now has sub folders for `spirv-builder-cli`'s and `rust-gpu` repos. * `spirv-crate-template` is updated to Git with revision `82a0f69` because "0.9" doesn't seem to compile on Windows. Things to consider: * Can we remove `TARGET_SPECS` now, because we have a copy of the `rust-gpu` repo, we can get them from there instead? * What's the UX expectations for changing `spirv-std` versions or overriding `rust-gpu` versions and toolchain? I think in most cases `spirv-builder-cli` rebuilds should occur because the changes will cause cache directory changes. But I think it'd be good to at least manually test this. * Should the main build test be moved out into an integrations tests folder? * I'd still like to test each `spirv-builder-cli` feature, ie: `spirv-builder-pre-cli` and `spirv-builder-0_10`. We're currently only testing `spirv-builder-pre-cli`. --- .github/workflows/push.yaml | 19 +- Cargo.lock | 320 +++++++++++++++++------- Cargo.toml | 13 +- README.md | 89 +++++-- crates/cargo-gpu/Cargo.toml | 4 + crates/cargo-gpu/src/build.rs | 55 +++- crates/cargo-gpu/src/install.rs | 94 +++++-- crates/cargo-gpu/src/main.rs | 81 +++--- crates/cargo-gpu/src/spirv_cli.rs | 124 +++++---- crates/cargo-gpu/src/spirv_source.rs | 304 ++++++++++++++++++++++ crates/cargo-gpu/src/toml.rs | 41 +-- crates/shader-crate-template/Cargo.lock | 40 ++- crates/shader-crate-template/Cargo.toml | 7 +- crates/spirv-builder-cli/Cargo.toml | 33 ++- crates/spirv-builder-cli/src/main.rs | 1 + 15 files changed, 905 insertions(+), 320 deletions(-) create mode 100644 crates/cargo-gpu/src/spirv_source.rs diff --git a/.github/workflows/push.yaml b/.github/workflows/push.yaml index 6d561da..4eb468e 100644 --- a/.github/workflows/push.yaml +++ b/.github/workflows/push.yaml @@ -13,8 +13,12 @@ env: jobs: install-and-build-shaders: strategy: + fail-fast: false matrix: - os: [ubuntu-latest, macos-latest, windows-latest] + os: + - ubuntu-latest + - macos-latest + - windows-latest runs-on: ${{ matrix.os }} defaults: run: @@ -24,18 +28,15 @@ jobs: steps: - uses: actions/checkout@v2 - uses: moonrepo/setup-rust@v1 - - run: rustup default stable - - run: rustup update + - name: Install Rust toolchain + run: | + rustup default stable + rustup update - run: cargo test - - run: cargo install --path crates/cargo-gpu - - run: cargo gpu install - - run: cargo gpu build --shader-crate crates/shader-crate-template --output-dir test-shaders - - run: ls -lah test-shaders - - run: cat test-shaders/manifest.json clippy: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - uses: moonrepo/setup-rust@v1 - - run: cargo clippy + - run: cargo clippy -- --deny warnings diff --git a/Cargo.lock b/Cargo.lock index e27864f..88ba813 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,6 +1,6 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 3 +version = 4 [[package]] name = "aho-corasick" @@ -68,15 +68,15 @@ checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" [[package]] name = "bitflags" -version = "1.3.2" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" [[package]] -name = "bitflags" -version = "2.6.0" +name = "bytes" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" +checksum = "325918d6fe32f23b19878fe4b34794ae41fc19ddbe53b10571a4874d44ffd39b" [[package]] name = "cargo-gpu" @@ -85,12 +85,14 @@ dependencies = [ "chrono", "clap", "directories", - "env_logger", + "env_logger 0.10.2", + "http", "log", "relative-path", "serde", "serde_json", "spirv-builder-cli", + "test-log", "toml", ] @@ -140,7 +142,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.87", + "syn", ] [[package]] @@ -176,6 +178,15 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "env_filter" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f2c92ceda6ceec50f43169f9ee8424fe2db276791afde7b2cd8bc084cb376ab" +dependencies = [ + "log", +] + [[package]] name = "env_home" version = "0.1.0" @@ -195,12 +206,30 @@ dependencies = [ "termcolor", ] +[[package]] +name = "env_logger" +version = "0.11.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e13fa619b91fb2381732789fc5de83b45675e882f66623b7d8cb4f643017018d" +dependencies = [ + "anstream", + "anstyle", + "env_filter", + "log", +] + [[package]] name = "equivalent" version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + [[package]] name = "getrandom" version = "0.2.15" @@ -212,24 +241,6 @@ dependencies = [ "wasi", ] -[[package]] -name = "glam" -version = "0.24.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5418c17512bdf42730f9032c74e1ae39afc408745ebb2acf72fbc4691c17945" -dependencies = [ - "libm", -] - -[[package]] -name = "glam" -version = "0.29.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc46dd3ec48fdd8e693a98d2b8bafae273a2d54c1de02a2a7e3d57d501f39677" -dependencies = [ - "libm", -] - [[package]] name = "hashbrown" version = "0.15.1" @@ -248,6 +259,17 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fbf6a919d6cf397374f7dfeeea91d974c7c0a7221d0d0f4f20d859d329e53fcc" +[[package]] +name = "http" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f16ca2af56261c99fba8bac40a10251ce8188205a4c448fbb745a2e4daa76fea" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + [[package]] name = "humantime" version = "2.1.0" @@ -288,16 +310,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" [[package]] -name = "libc" -version = "0.2.161" +name = "lazy_static" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e9489c2807c139ffd9c1794f4af0ebe86a828db53ecdc7fea2111d0fed085d1" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" [[package]] -name = "libm" -version = "0.2.11" +name = "libc" +version = "0.2.161" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8355be11b20d696c8f18f6cc018c4e372165b1fa8126cef092399c9951984ffa" +checksum = "8e9489c2807c139ffd9c1794f4af0ebe86a828db53ecdc7fea2111d0fed085d1" [[package]] name = "libredox" @@ -305,7 +327,7 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" dependencies = [ - "bitflags 2.6.0", + "bitflags", "libc", ] @@ -315,12 +337,31 @@ version = "0.4.22" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" +[[package]] +name = "matchers" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" +dependencies = [ + "regex-automata 0.1.10", +] + [[package]] name = "memchr" version = "2.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" +[[package]] +name = "nu-ansi-term" +version = "0.46.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" +dependencies = [ + "overload", + "winapi", +] + [[package]] name = "num-traits" version = "0.2.19" @@ -328,15 +369,32 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", - "libm", ] +[[package]] +name = "once_cell" +version = "1.20.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" + [[package]] name = "option-ext" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" +[[package]] +name = "overload" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" + +[[package]] +name = "pin-project-lite" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "915a1e146535de9163f3987b8944ed8cf49a18bb0056bcebcdcece385cece4ff" + [[package]] name = "proc-macro2" version = "1.0.89" @@ -374,8 +432,17 @@ checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" dependencies = [ "aho-corasick", "memchr", - "regex-automata", - "regex-syntax", + "regex-automata 0.4.8", + "regex-syntax 0.8.5", +] + +[[package]] +name = "regex-automata" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" +dependencies = [ + "regex-syntax 0.6.29", ] [[package]] @@ -386,9 +453,15 @@ checksum = "368758f23274712b504848e9d5a6f010445cc8b87a7cdb4d7cbee666c1288da3" dependencies = [ "aho-corasick", "memchr", - "regex-syntax", + "regex-syntax 0.8.5", ] +[[package]] +name = "regex-syntax" +version = "0.6.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" + [[package]] name = "regex-syntax" version = "0.8.5" @@ -401,14 +474,6 @@ version = "1.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ba39f3699c378cd8970968dcbff9c43159ea4cfbd88d43c00b22f2ef10a435d2" -[[package]] -name = "rust-gpu-shader-crate-template" -version = "0.1.0" -dependencies = [ - "glam 0.29.2", - "spirv-std", -] - [[package]] name = "ryu" version = "1.0.18" @@ -432,7 +497,7 @@ checksum = "de523f781f095e28fa605cdce0f8307e451cc0fd14e2eb4cd2e98a355b147766" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn", ] [[package]] @@ -456,66 +521,33 @@ dependencies = [ "serde", ] +[[package]] +name = "sharded-slab" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" +dependencies = [ + "lazy_static", +] + [[package]] name = "spirv-builder-cli" version = "0.1.0" dependencies = [ "env_home", - "env_logger", + "env_logger 0.10.2", "log", "serde", "serde_json", "toml", ] -[[package]] -name = "spirv-std" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68c3c0972a2df79abe2c8af2fe7f7937a9aa558b6a1f78fc5edf93f4d480d757" -dependencies = [ - "bitflags 1.3.2", - "glam 0.24.2", - "num-traits", - "spirv-std-macros", - "spirv-std-types", -] - -[[package]] -name = "spirv-std-macros" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73f776bf9f2897ea7acff15d7753711fdf1693592bd7459a01c394262b1df45c" -dependencies = [ - "proc-macro2", - "quote", - "spirv-std-types", - "syn 1.0.109", -] - -[[package]] -name = "spirv-std-types" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a73417b7d72d95b4995c840dceb4e3b4bcbad4ff7f35df9c1655b6826c18d3a9" - [[package]] name = "strsim" version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" -[[package]] -name = "syn" -version = "1.0.109" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - [[package]] name = "syn" version = "2.0.87" @@ -536,6 +568,28 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "test-log" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3dffced63c2b5c7be278154d76b479f9f9920ed34e7574201407f0b14e2bbb93" +dependencies = [ + "env_logger 0.11.5", + "test-log-macros", + "tracing-subscriber", +] + +[[package]] +name = "test-log-macros" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5999e24eaa32083191ba4e425deb75cdf25efefabe5aaccb7446dd0d4122a3f5" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "thiserror" version = "1.0.68" @@ -553,7 +607,17 @@ checksum = "a7c61ec9a6f64d2793d8a45faba21efbe3ced62a886d44c36a009b2b519b4c7e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn", +] + +[[package]] +name = "thread_local" +version = "1.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c" +dependencies = [ + "cfg-if", + "once_cell", ] [[package]] @@ -590,6 +654,54 @@ dependencies = [ "winnow", ] +[[package]] +name = "tracing" +version = "0.1.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" +dependencies = [ + "pin-project-lite", + "tracing-core", +] + +[[package]] +name = "tracing-core" +version = "0.1.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e672c95779cf947c5311f83787af4fa8fffd12fb27e4993211a84bdfd9610f9c" +dependencies = [ + "once_cell", + "valuable", +] + +[[package]] +name = "tracing-log" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" +dependencies = [ + "log", + "once_cell", + "tracing-core", +] + +[[package]] +name = "tracing-subscriber" +version = "0.3.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8189decb5ac0fa7bc8b96b7cb9b2701d60d48805aca84a238004d665fcc4008" +dependencies = [ + "matchers", + "nu-ansi-term", + "once_cell", + "regex", + "sharded-slab", + "thread_local", + "tracing", + "tracing-core", + "tracing-log", +] + [[package]] name = "unicode-ident" version = "1.0.13" @@ -602,12 +714,34 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" +[[package]] +name = "valuable" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" + [[package]] name = "wasi" version = "0.11.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + [[package]] name = "winapi-util" version = "0.1.9" @@ -617,6 +751,12 @@ dependencies = [ "windows-sys 0.59.0", ] +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + [[package]] name = "windows-sys" version = "0.48.0" diff --git a/Cargo.toml b/Cargo.toml index 9dd7fcb..f8122de 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,11 +1,14 @@ [workspace] members = [ "crates/cargo-gpu", - "crates/shader-crate-template" ] exclude = [ - "crates/spirv-builder-cli" + "crates/spirv-builder-cli", + + # This currently needs to be excluded because it depends on a version of `rust-gpu` that + # uses a toolchain whose Cargo version doesn't recognise version 4 of `Cargo.lock`. + "crates/shader-crate-template" ] resolver = "2" @@ -16,11 +19,13 @@ chrono = { version = "0.4.38", default-features = false } directories = "5.0.1" env_home = "0.1.0" env_logger = "0.10" +http = "1.2.0" log = "0.4" relative-path = "1.9.3" serde = { version = "1.0.214", features = ["derive"] } serde_json = "1.0.132" toml = "0.8.19" +test-log = "0.2.16" [workspace.lints.rust] missing_docs = "warn" @@ -46,7 +51,9 @@ pattern_type_mismatch = { level = "allow", priority = 1 } print_stdout = { level = "allow", priority = 1 } std_instead_of_alloc = { level = "allow", priority = 1 } -# TODO: Try to not depend on these lints +# TODO: Try to not depend on allowing these lints unwrap_used = { level = "allow", priority = 1 } +get_unwrap = { level = "allow", priority = 1 } +expect_used = { level = "allow", priority = 1 } panic = { level = "allow", priority = 1 } diff --git a/README.md b/README.md index 382fdfd..e0a2b1f 100644 --- a/README.md +++ b/README.md @@ -1,22 +1,24 @@ # cargo-gpu + Command line tool for building Rust shaders using rust-gpu. ## Getting Started ### Installation -To install the tool ensure you have `rustup`. Then run: + +To install the tool ensure you have `rustup`. Then run: ``` cargo install --git https://github.com/rust-gpu/cargo-gpu ``` -After that you can use `cargo gpu` to compile your shader crates with: +After that you can use `cargo gpu` to compile your shader crates with: ``` cargo gpu build ``` -This plain invocation will compile the crate in the current directory and +This plain invocation will compile the crate in the current directory and place the compiled shaders in the current directory. Use `cargo gpu help` to see other options :) @@ -33,13 +35,31 @@ cd shader-crate-template cargo gpu build ``` +## How it works + +Behind the scenes `cargo gpu` compiles a custom [codegen backend](https://doc.rust-lang.org/beta/unstable-book/compiler-flags/codegen-backend.html) +for `rustc` that allows emitting [SPIR-V](https://www.khronos.org/spir/) assembly, instead of the conventional LLVM assembly. SPIR-V is a dedicated +graphics language that is aimed to be open and portable so that it works with as many drivers and devices as possible. + +With the custom codegen backend (`rustc_codegen_spirv`) `cargo gpu` then compiles the shader it is pointed to. However, because custom codegen backends +are currently [an unstable feature](https://github.com/rust-lang/rust/issues/77933), `cargo gpu` also needs to install a "nightly" version of Rust. In +the usage instructions the backend and nightly Rust version are referred to as "artefacts" and can be explicitly managed with the arguments to the +`install` subcommand. + +> [!TIP] +> Whilst `cargo gpu` attempts to isolate shader compilation as much possible, if the shader crate is contained in a workspace then it's possible that +> the nightly version required by the shader is, ironically, older than the Rust/Cargo versions required by the workspace. Say for instance the +> workspace might use a newer `Cargo.lock` layout not supported by the pinned version of the shader crate's custom codegen backend. The solution to +> this is to either exclude the shader from the workspace, or upgrade the shader's `spirv-std` dependency to the latest. + ## Usage -``` +```` Commands: install Install rust-gpu compiler artifacts build Compile a shader crate to SPIR-V toml Compile a shader crate according to the `cargo gpu build` parameters found in the given toml file + show Show some useful values help Print this message or the help of the given subcommand(s) Options: @@ -57,17 +77,25 @@ Install rust-gpu compiler artifacts Usage: cargo-gpu install [OPTIONS] Options: - --spirv-builder - spirv-builder dependency, written just like in a Cargo.toml file + --shader-crate + Directory containing the shader crate to compile - [default: "{ git = \"https://github.com/Rust-GPU/rust-gpu.git\" }"] + [default: ./] + + --spirv-builder-source + Source of `spirv-builder` dependency Eg: "https://github.com/Rust-GPU/rust-gpu" + + --spirv-builder-version + Version of `spirv-builder` dependency. + * If `--spirv-builder-source` is not set, then this is assumed to be a crates.io semantic + 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. --rust-toolchain Rust toolchain channel to use to build `spirv-builder`. - This must match the `spirv_builder` argument. - - [default: nightly-2024-04-24] + This must be compatible with the `spirv_builder` argument as defined in the `rust-gpu` repo. --force-spirv-cli-rebuild Force `spirv-builder-cli` and `rustc_codegen_spirv` to be rebuilt @@ -83,26 +111,29 @@ Compile a shader crate to SPIR-V Usage: cargo-gpu build [OPTIONS] Options: - --spirv-builder - spirv-builder dependency, written just like in a Cargo.toml file + --shader-crate + Directory containing the shader crate to compile + + [default: ./] - [default: "{ git = \"https://github.com/Rust-GPU/rust-gpu.git\" }"] + --spirv-builder-source + Source of `spirv-builder` dependency Eg: "https://github.com/Rust-GPU/rust-gpu" + + --spirv-builder-version + Version of `spirv-builder` dependency. + * If `--spirv-builder-source` is not set, then this is assumed to be a crates.io semantic + 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. --rust-toolchain Rust toolchain channel to use to build `spirv-builder`. - This must match the `spirv_builder` argument. - - [default: nightly-2024-04-24] + This must be compatible with the `spirv_builder` argument as defined in the `rust-gpu` repo. --force-spirv-cli-rebuild Force `spirv-builder-cli` and `rustc_codegen_spirv` to be rebuilt - --shader-crate - Directory containing the shader crate to compile - - [default: ./] - --shader-target Shader target @@ -161,4 +192,18 @@ Options: -h, --help Print help (see a summary with '-h') -``` + +* Show + +Show some useful values + +Usage: cargo-gpu show [OPTIONS] + +Options: + --cache-directory + Displays the location of the cache directory + + -h, --help + Print help + +```` diff --git a/crates/cargo-gpu/Cargo.toml b/crates/cargo-gpu/Cargo.toml index 0935ad9..e6043d1 100644 --- a/crates/cargo-gpu/Cargo.toml +++ b/crates/cargo-gpu/Cargo.toml @@ -19,6 +19,10 @@ serde.workspace = true serde_json.workspace = true toml.workspace = true chrono.workspace = true +http.workspace = true + +[dev-dependencies] +test-log.workspace = true # Enable incremental by default in release mode. [profile.release] diff --git a/crates/cargo-gpu/src/build.rs b/crates/cargo-gpu/src/build.rs index 665dd20..d6c9016 100644 --- a/crates/cargo-gpu/src/build.rs +++ b/crates/cargo-gpu/src/build.rs @@ -12,11 +12,7 @@ use crate::{install::Install, target_spec_dir}; pub struct Build { /// Install the `rust-gpu` compiler and components #[clap(flatten)] - install: Install, - - /// Directory containing the shader crate to compile. - #[clap(long, default_value = "./")] - pub shader_crate: std::path::PathBuf, + pub install: Install, /// Shader target. #[clap(long, default_value = "spirv-unknown-vulkan1.2")] @@ -46,17 +42,17 @@ impl Build { self.output_dir = self.output_dir.canonicalize().unwrap(); // Ensure the shader crate exists - self.shader_crate = self.shader_crate.canonicalize().unwrap(); + self.install.shader_crate = self.install.shader_crate.canonicalize().unwrap(); assert!( - self.shader_crate.exists(), + self.install.shader_crate.exists(), "shader crate '{}' does not exist. (Current dir is '{}')", - self.shader_crate.display(), + self.install.shader_crate.display(), std::env::current_dir().unwrap().display() ); let spirv_builder_args = spirv_builder_cli::Args { dylib_path, - shader_crate: self.shader_crate.clone(), + shader_crate: self.install.shader_crate.clone(), shader_target: self.shader_target.clone(), path_to_target_spec: target_spec_dir().join(format!("{}.json", self.shader_target)), no_default_features: self.no_default_features, @@ -101,8 +97,10 @@ impl Build { use relative_path::PathExt as _; let path = self.output_dir.join(filepath.file_name().unwrap()); std::fs::copy(&filepath, &path).unwrap(); - let path_relative_to_shader_crate = - path.relative_to(&self.shader_crate).unwrap().to_path(""); + let path_relative_to_shader_crate = path + .relative_to(&self.install.shader_crate) + .unwrap() + .to_path(""); Linkage::new(entry, path_relative_to_shader_crate) }, ) @@ -140,3 +138,38 @@ impl Build { } } } + +#[cfg(test)] +mod test { + use crate::{Cli, Command}; + + use super::*; + + #[test_log::test] + fn builder_from_params() { + crate::test::tests_teardown(); + + let shader_crate_path = crate::test::shader_crate_template_path(); + let output_dir = shader_crate_path.join("shaders"); + + let args = [ + "target/debug/cargo-gpu", + "build", + "--shader-crate", + &format!("{}", shader_crate_path.display()), + "--output-dir", + &format!("{}", output_dir.display()), + ]; + if let Cli { + command: Command::Build(mut build), + } = Cli::parse_from(args) + { + assert_eq!(shader_crate_path, build.install.shader_crate); + assert_eq!(output_dir, build.output_dir); + + build.run(); + } else { + panic!("was not a build command"); + } + } +} diff --git a/crates/cargo-gpu/src/install.rs b/crates/cargo-gpu/src/install.rs index 68d4f4c..e3d7c0b 100644 --- a/crates/cargo-gpu/src/install.rs +++ b/crates/cargo-gpu/src/install.rs @@ -1,7 +1,7 @@ //! Install a dedicated per-shader crate that has the `rust-gpu` compiler in it. use std::io::Write as _; -use crate::{cache_dir, spirv_cli::Spirv, target_spec_dir}; +use crate::{cache_dir, spirv_cli::SpirvCli, spirv_source::SpirvSource, target_spec_dir}; /// These are the files needed to create the dedicated, per-shader `rust-gpu` builder create. const SPIRV_BUILDER_FILES: &[(&str, &str)] = &[ @@ -86,15 +86,32 @@ const TARGET_SPECS: &[(&str, &str)] = &[ /// `cargo gpu install` #[derive(clap::Parser, Debug)] pub struct Install { - /// spirv-builder dependency, written just like in a Cargo.toml file. - #[clap(long, default_value = Spirv::DEFAULT_DEP)] - spirv_builder: String, + /// Directory containing the shader crate to compile. + #[clap(long, default_value = "./")] + pub shader_crate: std::path::PathBuf, + + #[expect( + clippy::doc_markdown, + reason = "The URL should appear literally like this. But Clippy wants it to be a in markdown clickable link" + )] + /// Source of `spirv-builder` dependency + /// Eg: "https://github.com/Rust-GPU/rust-gpu" + #[clap(long)] + spirv_builder_source: Option, + + /// Version of `spirv-builder` dependency. + /// * If `--spirv-builder-source` is not set, then this is assumed to be a crates.io semantic + /// 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)] + spirv_builder_version: Option, /// Rust toolchain channel to use to build `spirv-builder`. /// /// This must be compatible with the `spirv_builder` argument as defined in the `rust-gpu` repo. - #[clap(long, default_value = Spirv::DEFAULT_CHANNEL)] - rust_toolchain: String, + #[clap(long)] + rust_toolchain: Option, /// Force `spirv-builder-cli` and `rustc_codegen_spirv` to be rebuilt. #[clap(long)] @@ -102,30 +119,61 @@ pub struct Install { } impl Install { - /// Returns a [`Spirv`] instance, responsible for ensuring the right version of the `spirv-builder-cli` crate. - fn spirv_cli(&self) -> Spirv { - Spirv { - dep: self.spirv_builder.clone(), - channel: self.rust_toolchain.clone(), - } + /// Returns a [`SpirvCLI`] instance, responsible for ensuring the right version of the `spirv-builder-cli` crate. + fn spirv_cli(&self, shader_crate_path: &std::path::PathBuf) -> SpirvCli { + SpirvCli::new( + shader_crate_path, + self.spirv_builder_source.clone(), + self.spirv_builder_version.clone(), + self.rust_toolchain.clone(), + ) } /// Create the `spirv-builder-cli` crate. fn write_source_files(&self) { - let cli = self.spirv_cli(); - let checkout = cli.cached_checkout_path(); + let spirv_cli = self.spirv_cli(&self.shader_crate); + let checkout = spirv_cli.cached_checkout_path(); std::fs::create_dir_all(checkout.join("src")).unwrap(); for (filename, contents) in SPIRV_BUILDER_FILES { log::debug!("writing {filename}"); let path = checkout.join(filename); let mut file = std::fs::File::create(&path).unwrap(); - let replaced_contents = contents - .replace("${SPIRV_BUILDER_SOURCE}", &cli.dep) - .replace("${CHANNEL}", &cli.channel); + let mut replaced_contents = contents.replace("${CHANNEL}", &spirv_cli.channel); + if filename == &"Cargo.toml" { + replaced_contents = Self::update_cargo_toml(&replaced_contents, &spirv_cli.source); + } file.write_all(replaced_contents.as_bytes()).unwrap(); } } + /// Create the `spirv-builder-cli` crate. + fn update_cargo_toml(contents: &str, spirv_source: &SpirvSource) -> String { + let updated = contents.lines().map(|line| { + if line.contains("${AUTO-REPLACE-SOURCE}") { + let replaced_line = match spirv_source { + SpirvSource::CratesIO(_) => String::new(), + SpirvSource::Git((repo, _)) => format!("git = \"{repo}\""), + SpirvSource::Path((path, _)) => format!("path = \"{path}\""), + }; + return format!("{replaced_line}\n"); + } + + if line.contains("${AUTO-REPLACE-VERSION}") { + let replaced_line = match spirv_source { + SpirvSource::CratesIO(version) | SpirvSource::Path((_, version)) => { + format!("version = \"{}\"", version.replace('v', "")) + } + SpirvSource::Git((_, revision)) => format!("rev = \"{revision}\""), + }; + return format!("{replaced_line}\n"); + } + + format!("{line}\n") + }); + + updated.collect() + } + /// Add the target spec files to the crate. fn write_target_spec_files(&self) { for (filename, contents) in TARGET_SPECS { @@ -150,8 +198,7 @@ impl Install { panic!("could not create cache dir"); }); - let spirv_version = self.spirv_cli(); - spirv_version.ensure_version_channel_compatibility(); + let spirv_version = self.spirv_cli(&self.shader_crate); spirv_version.ensure_toolchain_and_components_exist(); let checkout = spirv_version.cached_checkout_path(); @@ -191,7 +238,7 @@ impl Install { command.args([ "--features", - &Self::get_required_spirv_builder_version(&spirv_version.channel), + &Self::get_required_spirv_builder_version(spirv_version.date), ]); log::debug!("building artifacts with `{:?}`", command); @@ -237,16 +284,13 @@ impl Install { /// here we choose the right Cargo feature to enable/disable code in `spirv-builder-cli`. /// /// TODO: - /// * Download the actual `rust-gpu` repo as pinned in the shader's `Cargo.lock` and get the - /// `spirv-builder` version from there. /// * Warn the user that certain `cargo-gpu` features aren't available when building with /// older versions of `spirv-builder`, eg setting the target spec. - fn get_required_spirv_builder_version(toolchain_channel: &str) -> String { + fn get_required_spirv_builder_version(date: chrono::NaiveDate) -> String { let parse_date = chrono::NaiveDate::parse_from_str; - let datetime = parse_date(toolchain_channel, "nightly-%Y-%m-%d").unwrap(); let pre_cli_date = parse_date("2024-04-24", "%Y-%m-%d").unwrap(); - if datetime < pre_cli_date { + if date < pre_cli_date { "spirv-builder-pre-cli" } else { "spirv-builder-0_10" diff --git a/crates/cargo-gpu/src/main.rs b/crates/cargo-gpu/src/main.rs index 542b847..267fd14 100644 --- a/crates/cargo-gpu/src/main.rs +++ b/crates/cargo-gpu/src/main.rs @@ -60,6 +60,7 @@ mod build; mod install; mod show; mod spirv_cli; +mod spirv_source; mod toml; fn main() { @@ -118,13 +119,21 @@ pub(crate) struct Cli { } fn cache_dir() -> std::path::PathBuf { - directories::BaseDirs::new() + let dir = directories::BaseDirs::new() .unwrap_or_else(|| { log::error!("could not find the user home directory"); panic!("cache_dir failed"); }) .cache_dir() - .join("rust-gpu") + .join("rust-gpu"); + + if cfg!(test) { + let thread_id = std::thread::current().id(); + let id = format!("{thread_id:?}").replace('(', "-").replace(')', ""); + dir.join("tests").join(id) + } else { + dir + } } /// Location of the target spec metadata files @@ -171,55 +180,33 @@ fn write_help(buffer: &mut impl std::io::Write, cmd: &mut clap::Command, _depth: } } +/// 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() +} + #[cfg(test)] mod test { - use spirv_cli::Spirv as SpirvCLI; - - use super::*; - - #[test] - fn cached_checkout_dir_sanity() { - // Test that - let spirv = SpirvCLI::default(); - let dir = spirv.cached_checkout_path(); - let name = dir - .file_name() - .unwrap() - .to_str() - .map(std::string::ToString::to_string) - .unwrap(); - assert_eq!( - "git_https___github_com_Rust-GPU_rust-gpu_git+nightly-2024-04-24", - &name - ); + use crate::cache_dir; + + pub fn shader_crate_template_path() -> std::path::PathBuf { + let project_base = std::path::PathBuf::from(env!("CARGO_MANIFEST_DIR")); + project_base.join("../shader-crate-template") } - #[test] - fn builder_from_params() { - let shader_crate = std::path::PathBuf::from("../shader-crate-template"); - let output_dir = std::path::PathBuf::from("../shader-crate-template/shaders"); - let args = [ - "target/debug/cargo-gpu", - "build", - "--shader-crate", - &format!("{}", shader_crate.display()), - "--output-dir", - &format!("{}", output_dir.display()), - ]; - if let Cli { - command: Command::Build(mut build), - } = Cli::parse_from(args) - { - assert_eq!(shader_crate, build.shader_crate); - assert_eq!(output_dir, build.output_dir); - - // TODO: - // What's the best way to reset caches for this? For example we could add a - // `--force-spirv-cli-rebuild`, but that would slow down each test. But without - // something like that we might not be getting actual idempotent tests. - build.run(); - } else { - panic!("was not a build command"); + pub fn tests_teardown() { + let cache_dir = cache_dir(); + if !cache_dir.exists() { + return; } + std::fs::remove_dir_all(cache_dir).unwrap(); } } diff --git a/crates/cargo-gpu/src/spirv_cli.rs b/crates/cargo-gpu/src/spirv_cli.rs index 4c114b0..2355530 100644 --- a/crates/cargo-gpu/src/spirv_cli.rs +++ b/crates/cargo-gpu/src/spirv_cli.rs @@ -1,64 +1,70 @@ -//! Install the relevant Rust compiler and toolchain components required by the version of -//! `rust-gpu` defined in the shader. -use crate::cache_dir; +//! Query the shader crate to find what version of `rust-gpu` it depends on. +//! Then ensure that the relevant Rust toolchain and components are installed. -/// The canonical pairs of `rust-gpu` version to `rust-gpu` Rust toolchain channel. -/// -/// TODO: We may be able to automate this by checking out the locked version of `spirv-std` in the -/// shader's crate. -const SPIRV_STD_TOOLCHAIN_PAIRS: &[(&str, &str)] = &[("0.10", "nightly-2024-04-24")]; +use crate::spirv_source::SpirvSource; /// Cargo dependency for `spirv-builder` and the rust toolchain channel. #[derive(Debug, Clone)] -pub struct Spirv { - /// The version of `rust-gpu`, eg `"0.10"` or `"{ git = "https://github.com/Rust-GPU/rust-gpu.git" }` - pub dep: String, - //// The toolchain that `rust-gpu` uses, eg "nightly-2024-04-24" +pub struct SpirvCli { + #[expect( + clippy::doc_markdown, + reason = "The URL should appear literally like this. But Clippy wants it to be a in markdown clickable link" + )] + /// The source and version of `rust-gpu`. + /// Eg: + /// * From crates.io with version "0.10.0" + /// * From Git with: + /// - a repo of "https://github.com/Rust-GPU/rust-gpu.git" + /// - a revision of "abc213" + pub source: SpirvSource, + /// The toolchain channel that `rust-gpu` uses, eg "nightly-2024-04-24" pub channel: String, + /// The date of the pinned version of `rust-gpu` + pub date: chrono::NaiveDate, } -impl Default for Spirv { - fn default() -> Self { - Self { - dep: Self::DEFAULT_DEP.into(), - channel: Self::DEFAULT_CHANNEL.into(), - } - } -} - -impl core::fmt::Display for Spirv { +impl core::fmt::Display for SpirvCli { #[expect( clippy::min_ident_chars, reason = "It's a core library trait implementation" )] fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - format!("{}+{}", self.dep, self.channel).fmt(f) + format!("{}+{}", self.source, self.channel).fmt(f) } } -impl Spirv { - /// The default `rust-gpu` dependency defintion - pub const DEFAULT_DEP: &str = r#"{ git = "https://github.com/Rust-GPU/rust-gpu.git" }"#; - /// The default `rust-gpu` toolchain - pub const DEFAULT_CHANNEL: &str = "nightly-2024-04-24"; +impl SpirvCli { + /// Create instance + pub fn new( + shader_crate_path: &std::path::PathBuf, + maybe_rust_gpu_source: Option, + maybe_rust_gpu_version: Option, + maybe_rust_gpu_channel: Option, + ) -> Self { + let (default_rust_gpu_source, rust_gpu_date, default_rust_gpu_channel) = + SpirvSource::get_rust_gpu_deps_from_shader(shader_crate_path); - /// Returns a string suitable to use as a directory. - /// - /// Created from the spirv-builder source dep and the rustc channel. - fn to_dirname(&self) -> String { - self.to_string() - .replace( - [std::path::MAIN_SEPARATOR, '\\', '/', '.', ':', '@', '='], - "_", - ) - .split(['{', '}', ' ', '\n', '"', '\'']) - .collect::>() - .concat() + let mut maybe_spirv_source: Option = None; + if let Some(rust_gpu_version) = maybe_rust_gpu_version { + let mut source = SpirvSource::CratesIO(rust_gpu_version.clone()); + if let Some(rust_gpu_source) = maybe_rust_gpu_source { + source = SpirvSource::Git((rust_gpu_source, rust_gpu_version)); + } + maybe_spirv_source = Some(source); + } + + Self { + source: maybe_spirv_source.unwrap_or(default_rust_gpu_source), + channel: maybe_rust_gpu_channel.unwrap_or(default_rust_gpu_channel), + date: rust_gpu_date, + } } /// Create and/or return the cache directory pub fn cached_checkout_path(&self) -> std::path::PathBuf { - let checkout_dir = cache_dir().join(self.to_dirname()); + let checkout_dir = crate::cache_dir() + .join("spirv-builder-cli") + .join(crate::to_dirname(self.to_string().as_ref())); std::fs::create_dir_all(&checkout_dir).unwrap_or_else(|error| { log::error!( "could not create checkout dir '{}': {error}", @@ -70,20 +76,6 @@ impl Spirv { checkout_dir } - /// Ensure that the requested `rust-gpu` version/toolchain are known to be canonically - /// compatible. - /// - /// TODO: We may be able to automatically get the pair by downloading the `rust-gpu` repo as defined by the - /// `spriv-std` dependency in the shader. - pub fn ensure_version_channel_compatibility(&self) { - for (version, channel) in SPIRV_STD_TOOLCHAIN_PAIRS { - assert!( - !(version.starts_with(&self.dep) && channel != &self.channel), - "expected spirv-std version to be matched with rust toolchain channel {channel}" - ); - } - } - /// Use `rustup` to install the toolchain and components, if not already installed. /// /// Pretty much runs: @@ -158,3 +150,25 @@ impl Spirv { } } } + +#[cfg(test)] +mod test { + use super::*; + + #[test_log::test] + fn cached_checkout_dir_sanity() { + let shader_template_path = crate::test::shader_crate_template_path(); + let spirv = SpirvCli::new(&shader_template_path, None, None, None); + let dir = spirv.cached_checkout_path(); + let name = dir + .file_name() + .unwrap() + .to_str() + .map(std::string::ToString::to_string) + .unwrap(); + assert_eq!( + "https___github_com_Rust-GPU_rust-gpu+82a0f69+nightly-2024-04-24", + &name + ); + } +} diff --git a/crates/cargo-gpu/src/spirv_source.rs b/crates/cargo-gpu/src/spirv_source.rs new file mode 100644 index 0000000..6e8ab81 --- /dev/null +++ b/crates/cargo-gpu/src/spirv_source.rs @@ -0,0 +1,304 @@ +//! Use the shader that we're compiling as the default source for which version of `rust-gpu` to use. +//! +//! We do this by calling `cargo tree` inside the shader's crate to get the defined `spirv-std` +//! version. Then with that we `git checkout` the `rust-gpu` repo that corresponds to that version. +//! From there we can look at the source code to get the required Rust toolchain. + +/// The canonical `rust-gpu` URI +const RUST_GPU_REPO: &str = "https://github.com/Rust-GPU/rust-gpu"; + +/// The various sources that the `rust-gpu` repo can have. +/// Most commonly it will simply be the canonical version on crates.io. But it could also be the +/// Git version, or a fork. +#[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 + /// `rust-gpu` is the conventional crates.io version. + /// + /// `String` is the simple version like, "0.9.0" + CratesIO(String), + /// If the shader specifies a version like: + /// `spirv-std = { git = "https://github.com..." ... }` + /// then the source of `rust-gpu` is `Git`. + /// + /// `(String, String)` is the repo source and revision hash or tag. + Git((String, String)), + /// If the shader specifies a version like: + /// `spirv-std = { path = "/path/to/rust-gpu" ... }` + /// then the source of `rust-gpu` is `Path`. + /// + /// `(String, String)` is the repo path and the version. + Path((String, String)), +} + +impl core::fmt::Display for SpirvSource { + #[expect( + clippy::min_ident_chars, + reason = "It's a core library trait implementation" + )] + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + format!("{}+{}", self.to_repo(), self.to_version()).fmt(f) + } +} + +impl SpirvSource { + /// Look into the shader crate to get the version of `rust-gpu` it's using. + pub fn get_rust_gpu_deps_from_shader( + shader_crate_path: &std::path::PathBuf, + ) -> (Self, chrono::NaiveDate, String) { + let rust_gpu_source = Self::get_spirv_std_dep_definition(shader_crate_path); + + rust_gpu_source.ensure_repo_is_installed(); + rust_gpu_source.checkout(); + + let date = rust_gpu_source.get_version_date(); + let channel = Self::get_channel_from_toolchain_toml(&rust_gpu_source.to_dirname()); + + log::debug!("Parsed version, date and toolchain channel from shader-defined `rust-gpu`: {rust_gpu_source:?}, {date}, {channel}"); + + (rust_gpu_source, date, channel) + } + + /// Convert the source to just its version. + pub fn to_version(&self) -> String { + match self { + Self::CratesIO(version) | Self::Path((_, version)) => version.to_string(), + Self::Git((_, revision)) => revision.to_string(), + } + } + + /// Convert the source to just its repo or path. + fn to_repo(&self) -> String { + match self { + Self::CratesIO(_) => RUST_GPU_REPO.to_owned(), + Self::Git((repo, _)) => repo.to_owned(), + Self::Path((path, _)) => path.to_owned(), + } + } + + /// Convert the `rust-gpu` source into a string that can be used as a directory. + /// It needs to be dynamically created because an end-user might want to swap out the source, + /// maybe using their own fork for example. + fn to_dirname(&self) -> std::path::PathBuf { + let dir = crate::to_dirname(self.to_string().as_ref()); + crate::cache_dir().join("rust-gpu-repo").join(dir) + } + + /// Checkout the `rust-gpu` to the requested version. + fn checkout(&self) { + log::debug!( + "Checking out `rust-gpu` repo at {} to {}", + self.to_dirname().display(), + self.to_version() + ); + let output_checkout = std::process::Command::new("git") + .current_dir(self.to_dirname()) + .args(["checkout", self.to_version().as_ref()]) + .output() + .unwrap(); + assert!( + output_checkout.status.success(), + "couldn't checkout revision '{}' of `rust-gpu` at {}", + self.to_version(), + self.to_dirname().to_string_lossy() + ); + } + + /// Get the date of the version of `rust-gpu` used by the shader. This allows us to know what + /// features we can use in the `spirv-builder` crate. + fn get_version_date(&self) -> chrono::NaiveDate { + let date_format = "%Y-%m-%d"; + + log::debug!( + "Getting `rust-gpu` version date from {}", + self.to_dirname().display(), + ); + let output_date = std::process::Command::new("git") + .current_dir(self.to_dirname()) + .args([ + "show", + "--no-patch", + "--format=%cd", + format!("--date=format:'{date_format}'").as_ref(), + self.to_version().as_ref(), + ]) + .output() + .unwrap(); + assert!( + output_date.status.success(), + "couldn't get `rust-gpu` version date at for {} at {}", + self.to_version(), + self.to_dirname().to_string_lossy() + ); + let date_string = String::from_utf8_lossy(&output_date.stdout) + .to_string() + .trim() + .replace('\'', ""); + + log::debug!( + "Parsed date for version {}: {date_string}", + self.to_version() + ); + + chrono::NaiveDate::parse_from_str(&date_string, date_format).unwrap() + } + + /// Parse the `rust-toolchain.toml` in the working tree of the checked-out version of the `rust-gpu` repo. + fn get_channel_from_toolchain_toml(path: &std::path::PathBuf) -> String { + log::debug!("Parsing `rust-toolchain.toml` at {path:?} for the used toolchain"); + + let contents = std::fs::read_to_string(path.join("rust-toolchain.toml")).unwrap(); + let toml: toml::Table = toml::from_str(&contents).unwrap(); + let Some(toolchain) = toml.get("toolchain") else { + panic!("Couldn't find `[toolchain]` section in `rust-toolchain.toml` at {path:?}"); + }; + let Some(channel) = toolchain.get("channel") else { + panic!("Couldn't find `channel` field in `rust-toolchain.toml` at {path:?}"); + }; + + channel.to_string().replace('"', "") + } + + /// Get the shader crate's `spirv_std = ...` definition in its `Cargo.toml` + fn get_spirv_std_dep_definition(shader_crate_path: &std::path::PathBuf) -> Self { + log::debug!("Running `cargo tree` on {}", shader_crate_path.display()); + let output_cargo_tree = std::process::Command::new("cargo") + .current_dir(shader_crate_path) + .args(["tree", "--workspace", "--depth", "1", "--prefix", "none"]) + .output() + .unwrap(); + assert!( + output_cargo_tree.status.success(), + "could not query shader's `Cargo.toml` for `spirv-std` dependency" + ); + let cargo_tree_string = String::from_utf8_lossy(&output_cargo_tree.stdout); + + let maybe_spirv_std_def = cargo_tree_string + .lines() + .find(|line| line.contains("spirv-std")); + + let Some(spirv_std_def) = maybe_spirv_std_def else { + panic!("`spirv-std` not found in shader's `Cargo.toml` at {shader_crate_path:?}:\n{cargo_tree_string}"); + }; + + Self::parse_spirv_std_source_and_version(spirv_std_def) + } + + /// Parse a string like: + /// `spirv-std v0.9.0 (https://github.com/Rust-GPU/rust-gpu?rev=54f6978c#54f6978c) (*)` + /// Which would return: + /// `SpirvSource::Git("https://github.com/Rust-GPU/rust-gpu", "54f6978c")` + fn parse_spirv_std_source_and_version(spirv_std_def: &str) -> Self { + let parts: Vec = spirv_std_def.split_whitespace().map(String::from).collect(); + let version = parts + .get(1) + .expect("Couldn't find `spirv_std` version in shader crate") + .to_owned(); + let mut source = Self::CratesIO(version.clone()); + + if parts.len() > 2 { + let mut source_string = parts.get(2).unwrap().to_owned(); + source_string = source_string.replace(['(', ')'], ""); + + let uri = source_string.parse::().unwrap(); + if uri.scheme().is_some() { + source = Self::parse_git_source(version, &uri); + } else { + source = Self::Path((source_string, version)); + } + } + + log::debug!("Parsed `rust-gpu` source and version: {source:?}"); + + source + } + + /// Parse a Git source like: `https://github.com/Rust-GPU/rust-gpu?rev=54f6978c#54f6978c` + fn parse_git_source(version: String, uri: &http::Uri) -> Self { + let mut revision = version; + + let repo = format!( + "{}://{}{}", + uri.scheme().unwrap(), + uri.host().unwrap(), + uri.path() + ); + + if let Some(query) = uri.query() { + let marker = "rev="; + let sanity_check = query.contains(marker) && query.split('=').count() == 2; + assert!(sanity_check, "revision not found in Git URI: {query}"); + revision = query.replace(marker, ""); + } + + Self::Git((repo, revision)) + } + + /// `git clone` the `rust-gpu` repo. We use it to get the required Rust toolchain to compile + /// the shader. + fn ensure_repo_is_installed(&self) { + if self.to_dirname().exists() { + log::debug!( + "Not cloning `rust-gpu` repo ({}) as it already exists at {}", + self.to_repo(), + self.to_dirname().to_string_lossy().as_ref(), + ); + return; + } + + log::debug!( + "Cloning `rust-gpu` repo {} to {}", + self.to_repo(), + self.to_dirname().to_string_lossy().as_ref(), + ); + + let output_clone = std::process::Command::new("git") + .args([ + "clone", + self.to_repo().as_ref(), + self.to_dirname().to_string_lossy().as_ref(), + ]) + .output() + .unwrap(); + + assert!( + output_clone.status.success(), + "couldn't clone `rust-gpu` {} to {}\n{}", + self.to_repo(), + self.to_dirname().to_string_lossy(), + String::from_utf8_lossy(&output_clone.stderr) + ); + } +} + +#[cfg(test)] +mod test { + use super::*; + + #[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_spirv_std_dep_definition(&shader_template_path); + assert_eq!( + source, + SpirvSource::Git(( + "https://github.com/Rust-GPU/rust-gpu".to_owned(), + "82a0f69".to_owned() + )) + ); + } + + #[test_log::test] + fn parsing_spirv_std_dep_for_git_source() { + let definition = + "spirv-std v9.9.9 (https://github.com/Rust-GPU/rust-gpu?rev=82a0f69#82a0f69) (*)"; + let source = SpirvSource::parse_spirv_std_source_and_version(definition); + assert_eq!( + source, + SpirvSource::Git(( + "https://github.com/Rust-GPU/rust-gpu".to_owned(), + "82a0f69".to_owned() + )) + ); + } +} diff --git a/crates/cargo-gpu/src/toml.rs b/crates/cargo-gpu/src/toml.rs index ab360ef..cf76f7d 100644 --- a/crates/cargo-gpu/src/toml.rs +++ b/crates/cargo-gpu/src/toml.rs @@ -37,25 +37,9 @@ pub struct Toml { impl Toml { /// Entrypoint pub fn run(&self) { - // Find the path to the toml file to use - let path = if self.path.is_file() && self.path.ends_with(".toml") { - self.path.clone() - } else { - let path = self.path.join("Cargo.toml"); - if path.is_file() { - path - } else { - log::error!("toml file '{}' is not a file", self.path.display()); - panic!("toml file '{}' is not a file", self.path.display()); - } - }; - - log::info!("using toml file '{}'", path.display()); + let (path, toml) = Self::parse_cargo_toml(self.path.clone()); // Determine if this is a workspace's Cargo.toml or a crate's Cargo.toml - let contents = std::fs::read_to_string(&path).unwrap(); - let toml: toml::Table = toml::from_str(&contents).unwrap(); - let (toml_type, table) = if toml.contains_key("workspace") { let table = Self::get_metadata_rustgpu_table(&toml, "workspace") .unwrap_or_else(|| { @@ -134,6 +118,29 @@ impl Toml { } } + /// Parse the contents of the shader's `Cargo.toml` + pub fn parse_cargo_toml(mut path: std::path::PathBuf) -> (std::path::PathBuf, toml::Table) { + // Find the path to the toml file to use + let parsed_path = if path.is_file() && path.ends_with(".toml") { + path + } else { + path = path.join("Cargo.toml"); + if path.is_file() { + path + } else { + log::error!("toml file '{}' is not a file", path.display()); + panic!("toml file '{}' is not a file", path.display()); + } + }; + + log::info!("using toml file '{}'", parsed_path.display()); + + let contents = std::fs::read_to_string(&parsed_path).unwrap(); + let toml: toml::Table = toml::from_str(&contents).unwrap(); + + (parsed_path, toml) + } + /// Parse the `[package.metadata.rust-gpu]` section. fn get_metadata_rustgpu_table<'toml>( toml: &'toml toml::Table, diff --git a/crates/shader-crate-template/Cargo.lock b/crates/shader-crate-template/Cargo.lock index d7a52c4..8a30859 100644 --- a/crates/shader-crate-template/Cargo.lock +++ b/crates/shader-crate-template/Cargo.lock @@ -1,6 +1,6 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 3 +version = 4 [[package]] name = "autocfg" @@ -16,18 +16,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "glam" -version = "0.24.2" +version = "0.29.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5418c17512bdf42730f9032c74e1ae39afc408745ebb2acf72fbc4691c17945" -dependencies = [ - "libm", -] - -[[package]] -name = "glam" -version = "0.29.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "480c9417a5dc586fc0c0cb67891170e59cc11e9dc79ba1c11ddd2c56ca3f3b90" +checksum = "dc46dd3ec48fdd8e693a98d2b8bafae273a2d54c1de02a2a7e3d57d501f39677" dependencies = [ "libm", ] @@ -50,9 +41,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.89" +version = "1.0.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f139b0662de085916d1fb67d2b4169d1addddda1919e696f3252b740b629986e" +checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0" dependencies = [ "unicode-ident", ] @@ -70,18 +61,17 @@ dependencies = [ name = "rust-gpu-shader-crate-template" version = "0.1.0" dependencies = [ - "glam 0.29.1", + "glam", "spirv-std", ] [[package]] name = "spirv-std" version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68c3c0972a2df79abe2c8af2fe7f7937a9aa558b6a1f78fc5edf93f4d480d757" +source = "git+https://github.com/Rust-GPU/rust-gpu?rev=82a0f69#82a0f69008414f51d59184763146caa6850ac588" dependencies = [ "bitflags", - "glam 0.24.2", + "glam", "num-traits", "spirv-std-macros", "spirv-std-types", @@ -90,8 +80,7 @@ dependencies = [ [[package]] name = "spirv-std-macros" version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73f776bf9f2897ea7acff15d7753711fdf1693592bd7459a01c394262b1df45c" +source = "git+https://github.com/Rust-GPU/rust-gpu?rev=82a0f69#82a0f69008414f51d59184763146caa6850ac588" dependencies = [ "proc-macro2", "quote", @@ -102,14 +91,13 @@ dependencies = [ [[package]] name = "spirv-std-types" version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a73417b7d72d95b4995c840dceb4e3b4bcbad4ff7f35df9c1655b6826c18d3a9" +source = "git+https://github.com/Rust-GPU/rust-gpu?rev=82a0f69#82a0f69008414f51d59184763146caa6850ac588" [[package]] name = "syn" -version = "1.0.109" +version = "2.0.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +checksum = "919d3b74a5dd0ccd15aeb8f93e7006bd9e14c295087c9896a110f490752bcf31" dependencies = [ "proc-macro2", "quote", @@ -118,6 +106,6 @@ dependencies = [ [[package]] name = "unicode-ident" -version = "1.0.13" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" +checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83" diff --git a/crates/shader-crate-template/Cargo.toml b/crates/shader-crate-template/Cargo.toml index 5d62ebf..3ec4841 100644 --- a/crates/shader-crate-template/Cargo.toml +++ b/crates/shader-crate-template/Cargo.toml @@ -8,14 +8,15 @@ crate-type = ["rlib", "cdylib"] # Dependencies for CPU and GPU code [dependencies] -spirv-std = { version = "0.9" } +# "v0.9" doesn't seem to compile on windows? +spirv-std = { git = "https://github.com/Rust-GPU/rust-gpu", rev = "82a0f69" } -# dependencies for GPU code +# Dependencies for GPU code [target.'cfg(target_arch = "spirv")'.dependencies] glam = { version = "0.29", default-features = false, features = ["libm"] } -# dependencies for CPU code +# Dependencies for CPU code [target.'cfg(not(target_arch = "spirv"))'.dependencies] glam = { version = "0.29", features = ["std"] } diff --git a/crates/spirv-builder-cli/Cargo.toml b/crates/spirv-builder-cli/Cargo.toml index 67f9ee8..c89b824 100644 --- a/crates/spirv-builder-cli/Cargo.toml +++ b/crates/spirv-builder-cli/Cargo.toml @@ -4,6 +4,11 @@ version = "0.1.0" edition = "2021" [lib] +path = "src/lib.rs" + +[[bin]] +name = "spirv-builder-cli" +path = "src/main.rs" [dependencies] env_home = "0.1.0" @@ -13,18 +18,6 @@ serde = "1.0.214" serde_json = "1.0.132" toml = "0.8.19" -[dependencies.spirv-builder-pre-cli] -package = "spirv-builder" -optional = true -git = "https://github.com/Rust-GPU/rust-gpu" -rev = "4c633aec" - -[dependencies.spirv-builder-0_10] -package = "spirv-builder" -optional = true -git = "https://github.com/Rust-GPU/rust-gpu" -rev = "60dcb82" - [features] default = ["spirv-builder-0_10"] # The `spirv-builder` before `cargo gpu` existed. It has an incompatible `SpirvBuilder` interface. @@ -32,3 +25,19 @@ spirv-builder-pre-cli = ["dep:spirv-builder-pre-cli"] # The first version that introduced `cargo gpu`. It has some extra `.builder()` args that make # dynamically changing build dependencies easier. spirv-builder-0_10 = ["dep:spirv-builder-0_10"] + +# NB: All the `${AUTO-REPLACE*}` tokens in each feature get replaced with the same values. +# This is because only one feature can ever be used at once and it makes it easier to just +# replace each token rather than figure out to what feature each token belongs. + +[dependencies.spirv-builder-pre-cli] +package = "spirv-builder" +optional = true +git = "https://github.com/Rust-GPU/rust-gpu" # ${AUTO-REPLACE-SOURCE} +rev = "4c633aec" # ${AUTO-REPLACE-VERSION} + +[dependencies.spirv-builder-0_10] +package = "spirv-builder" +optional = true +git = "https://github.com/Rust-GPU/rust-gpu" # ${AUTO-REPLACE-SOURCE} +rev = "60dcb82" # ${AUTO-REPLACE-VERSION} diff --git a/crates/spirv-builder-cli/src/main.rs b/crates/spirv-builder-cli/src/main.rs index 9c92b0a..a18a339 100644 --- a/crates/spirv-builder-cli/src/main.rs +++ b/crates/spirv-builder-cli/src/main.rs @@ -90,6 +90,7 @@ fn main() { } } + log::debug!("Calling `rust-gpu`'s `spirv-builder` library"); builder.build().unwrap() }; From e1b9e8c6cb1c6cd4e51ddb71716bf5d2820108d8 Mon Sep 17 00:00:00 2001 From: Schell Carl Scivally Date: Fri, 20 Dec 2024 11:00:18 +1300 Subject: [PATCH 03/10] Add test comment in spirv_source.rs --- crates/cargo-gpu/src/spirv_source.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/crates/cargo-gpu/src/spirv_source.rs b/crates/cargo-gpu/src/spirv_source.rs index 6e8ab81..24790cc 100644 --- a/crates/cargo-gpu/src/spirv_source.rs +++ b/crates/cargo-gpu/src/spirv_source.rs @@ -3,6 +3,8 @@ //! We do this by calling `cargo tree` inside the shader's crate to get the defined `spirv-std` //! version. Then with that we `git checkout` the `rust-gpu` repo that corresponds to that version. //! From there we can look at the source code to get the required Rust toolchain. +//! +//! This is just a test. /// The canonical `rust-gpu` URI const RUST_GPU_REPO: &str = "https://github.com/Rust-GPU/rust-gpu"; From 3f1ab564a2e136c6d2d20808bc7bee1ceec0b560 Mon Sep 17 00:00:00 2001 From: Schell Carl Scivally Date: Fri, 20 Dec 2024 10:18:09 +1300 Subject: [PATCH 04/10] make Git source respect revision, show source command --- Cargo.lock | 22 ++++++++ Cargo.toml | 1 + crates/cargo-gpu/Cargo.toml | 1 + crates/cargo-gpu/src/install.rs | 4 +- crates/cargo-gpu/src/show.rs | 35 ++++++++++-- crates/cargo-gpu/src/spirv_cli.rs | 5 +- crates/cargo-gpu/src/spirv_source.rs | 84 ++++++++++++++++++++-------- 7 files changed, 119 insertions(+), 33 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 88ba813..d11c416 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -91,6 +91,7 @@ dependencies = [ "relative-path", "serde", "serde_json", + "snafu", "spirv-builder-cli", "test-log", "toml", @@ -530,6 +531,27 @@ dependencies = [ "lazy_static", ] +[[package]] +name = "snafu" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "223891c85e2a29c3fe8fb900c1fae5e69c2e42415e3177752e8718475efa5019" +dependencies = [ + "snafu-derive", +] + +[[package]] +name = "snafu-derive" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03c3c6b7927ffe7ecaa769ee0e3994da3b8cafc8f444578982c83ecb161af917" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "spirv-builder-cli" version = "0.1.0" diff --git a/Cargo.toml b/Cargo.toml index f8122de..283e9ef 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,6 +24,7 @@ log = "0.4" relative-path = "1.9.3" serde = { version = "1.0.214", features = ["derive"] } serde_json = "1.0.132" +snafu = "0.8.5" toml = "0.8.19" test-log = "0.2.16" diff --git a/crates/cargo-gpu/Cargo.toml b/crates/cargo-gpu/Cargo.toml index e6043d1..67df799 100644 --- a/crates/cargo-gpu/Cargo.toml +++ b/crates/cargo-gpu/Cargo.toml @@ -17,6 +17,7 @@ log.workspace = true relative-path.workspace = true serde.workspace = true serde_json.workspace = true +snafu.workspace = true toml.workspace = true chrono.workspace = true http.workspace = true diff --git a/crates/cargo-gpu/src/install.rs b/crates/cargo-gpu/src/install.rs index e3d7c0b..7e79533 100644 --- a/crates/cargo-gpu/src/install.rs +++ b/crates/cargo-gpu/src/install.rs @@ -152,7 +152,7 @@ impl Install { if line.contains("${AUTO-REPLACE-SOURCE}") { let replaced_line = match spirv_source { SpirvSource::CratesIO(_) => String::new(), - SpirvSource::Git((repo, _)) => format!("git = \"{repo}\""), + SpirvSource::Git { url, .. } => format!("git = \"{url}\""), SpirvSource::Path((path, _)) => format!("path = \"{path}\""), }; return format!("{replaced_line}\n"); @@ -163,7 +163,7 @@ impl Install { SpirvSource::CratesIO(version) | SpirvSource::Path((_, version)) => { format!("version = \"{}\"", version.replace('v', "")) } - SpirvSource::Git((_, revision)) => format!("rev = \"{revision}\""), + SpirvSource::Git { rev, .. } => format!("rev = \"{rev}\""), }; return format!("{replaced_line}\n"); } diff --git a/crates/cargo-gpu/src/show.rs b/crates/cargo-gpu/src/show.rs index 24d5632..56f8c3b 100644 --- a/crates/cargo-gpu/src/show.rs +++ b/crates/cargo-gpu/src/show.rs @@ -2,20 +2,43 @@ use crate::cache_dir; +#[derive(Clone, Debug, clap::Parser)] +pub struct ShowSpirvSource { + /// The location of the shader-crate to inspect to determine its spirv-std dependency. + #[clap(long, default_value = "./")] + pub shader_crate: std::path::PathBuf, +} + +/// Different tidbits of information that can be queried at the command line. +#[derive(Clone, Debug, clap::Subcommand)] +pub enum Info { + /// Displays the location of the cache directory + CacheDirectory, + /// The source location of spirv-std + SpirvSource(ShowSpirvSource), +} + /// `cargo gpu show` #[derive(clap::Parser)] pub struct Show { - #[clap(long)] - /// Displays the location of the cache directory - cache_directory: bool, + /// Display information about rust-gpu + #[clap(subcommand)] + command: Info, } impl Show { /// Entrypoint pub fn run(self) { - if self.cache_directory { - log::info!("cache_directory: "); - println!("{}", cache_dir().display()); + log::info!("{:?}: ", self.command); + match self.command { + Info::CacheDirectory => { + println!("{}", cache_dir().display()); + } + Info::SpirvSource(ShowSpirvSource { shader_crate }) => { + let rust_gpu_source = + crate::spirv_source::SpirvSource::get_spirv_std_dep_definition(&shader_crate); + println!("{rust_gpu_source}"); + } } } } diff --git a/crates/cargo-gpu/src/spirv_cli.rs b/crates/cargo-gpu/src/spirv_cli.rs index 2355530..52c4c0e 100644 --- a/crates/cargo-gpu/src/spirv_cli.rs +++ b/crates/cargo-gpu/src/spirv_cli.rs @@ -48,7 +48,10 @@ impl SpirvCli { if let Some(rust_gpu_version) = maybe_rust_gpu_version { let mut source = SpirvSource::CratesIO(rust_gpu_version.clone()); if let Some(rust_gpu_source) = maybe_rust_gpu_source { - source = SpirvSource::Git((rust_gpu_source, rust_gpu_version)); + source = SpirvSource::Git { + url: rust_gpu_source, + rev: rust_gpu_version, + }; } maybe_spirv_source = Some(source); } diff --git a/crates/cargo-gpu/src/spirv_source.rs b/crates/cargo-gpu/src/spirv_source.rs index 24790cc..c12d39e 100644 --- a/crates/cargo-gpu/src/spirv_source.rs +++ b/crates/cargo-gpu/src/spirv_source.rs @@ -24,7 +24,7 @@ pub enum SpirvSource { /// then the source of `rust-gpu` is `Git`. /// /// `(String, String)` is the repo source and revision hash or tag. - Git((String, String)), + Git { url: String, rev: String }, /// If the shader specifies a version like: /// `spirv-std = { path = "/path/to/rust-gpu" ... }` /// then the source of `rust-gpu` is `Path`. @@ -39,7 +39,11 @@ impl core::fmt::Display for SpirvSource { reason = "It's a core library trait implementation" )] fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - format!("{}+{}", self.to_repo(), self.to_version()).fmt(f) + match self { + SpirvSource::CratesIO(version) => f.write_str(version), + SpirvSource::Git { url, rev } => f.write_str(&format!("{url}+{rev}")), + SpirvSource::Path((a, b)) => f.write_str(&format!("{a}+{b}")), + } } } @@ -65,7 +69,7 @@ impl SpirvSource { pub fn to_version(&self) -> String { match self { Self::CratesIO(version) | Self::Path((_, version)) => version.to_string(), - Self::Git((_, revision)) => revision.to_string(), + Self::Git { rev, .. } => rev.to_string(), } } @@ -73,7 +77,7 @@ impl SpirvSource { fn to_repo(&self) -> String { match self { Self::CratesIO(_) => RUST_GPU_REPO.to_owned(), - Self::Git((repo, _)) => repo.to_owned(), + Self::Git { url, .. } => url.to_owned(), Self::Path((path, _)) => path.to_owned(), } } @@ -162,7 +166,7 @@ impl SpirvSource { } /// Get the shader crate's `spirv_std = ...` definition in its `Cargo.toml` - fn get_spirv_std_dep_definition(shader_crate_path: &std::path::PathBuf) -> Self { + pub fn get_spirv_std_dep_definition(shader_crate_path: &std::path::PathBuf) -> Self { log::debug!("Running `cargo tree` on {}", shader_crate_path.display()); let output_cargo_tree = std::process::Command::new("cargo") .current_dir(shader_crate_path) @@ -178,6 +182,7 @@ impl SpirvSource { let maybe_spirv_std_def = cargo_tree_string .lines() .find(|line| line.contains("spirv-std")); + log::trace!(" found {maybe_spirv_std_def:?}"); let Some(spirv_std_def) = maybe_spirv_std_def else { panic!("`spirv-std` not found in shader's `Cargo.toml` at {shader_crate_path:?}:\n{cargo_tree_string}"); @@ -191,6 +196,7 @@ impl SpirvSource { /// Which would return: /// `SpirvSource::Git("https://github.com/Rust-GPU/rust-gpu", "54f6978c")` fn parse_spirv_std_source_and_version(spirv_std_def: &str) -> Self { + log::trace!("parsing spirv-std source and version from def: '{spirv_std_def}'"); let parts: Vec = spirv_std_def.split_whitespace().map(String::from).collect(); let version = parts .get(1) @@ -202,9 +208,21 @@ impl SpirvSource { let mut source_string = parts.get(2).unwrap().to_owned(); source_string = source_string.replace(['(', ')'], ""); + // Unfortunately Uri ignores the fragment/hash portion of the Uri. + // + // There's been a ticket open for years: + // + // + // So here we'll parse the fragment out of the source string by hand let uri = source_string.parse::().unwrap(); + let maybe_hash = if source_string.contains('#') { + let splits = source_string.split('#'); + splits.last().map(std::borrow::ToOwned::to_owned) + } else { + None + }; if uri.scheme().is_some() { - source = Self::parse_git_source(version, &uri); + source = Self::parse_git_source(version, &uri, maybe_hash); } else { source = Self::Path((source_string, version)); } @@ -216,9 +234,11 @@ impl SpirvSource { } /// Parse a Git source like: `https://github.com/Rust-GPU/rust-gpu?rev=54f6978c#54f6978c` - fn parse_git_source(version: String, uri: &http::Uri) -> Self { - let mut revision = version; - + fn parse_git_source(version: String, uri: &http::Uri, fragment: Option) -> Self { + log::trace!( + "parsing git source from version: '{version}' and uri: '{uri}' and fragment: {}", + fragment.as_deref().unwrap_or("?") + ); let repo = format!( "{}://{}{}", uri.scheme().unwrap(), @@ -226,14 +246,17 @@ impl SpirvSource { uri.path() ); - if let Some(query) = uri.query() { - let marker = "rev="; - let sanity_check = query.contains(marker) && query.split('=').count() == 2; - assert!(sanity_check, "revision not found in Git URI: {query}"); - revision = query.replace(marker, ""); - } + let rev = uri.query().map_or_else( + || fragment.unwrap_or(version), + |query| { + let marker = "rev="; + let sanity_check = query.contains(marker) && query.split('=').count() == 2; + assert!(sanity_check, "revision not found in Git URI: {query}"); + query.replace(marker, "") + }, + ); - Self::Git((repo, revision)) + Self::Git { url: repo, rev } } /// `git clone` the `rust-gpu` repo. We use it to get the required Rust toolchain to compile @@ -283,10 +306,10 @@ mod test { let source = SpirvSource::get_spirv_std_dep_definition(&shader_template_path); assert_eq!( source, - SpirvSource::Git(( - "https://github.com/Rust-GPU/rust-gpu".to_owned(), - "82a0f69".to_owned() - )) + SpirvSource::Git { + url: "https://github.com/Rust-GPU/rust-gpu".to_owned(), + rev: "82a0f69".to_owned() + } ); } @@ -297,10 +320,23 @@ mod test { let source = SpirvSource::parse_spirv_std_source_and_version(definition); assert_eq!( source, - SpirvSource::Git(( - "https://github.com/Rust-GPU/rust-gpu".to_owned(), - "82a0f69".to_owned() - )) + SpirvSource::Git { + url: "https://github.com/Rust-GPU/rust-gpu".to_owned(), + rev: "82a0f69".to_owned() + } + ); + } + + #[test_log::test] + fn parsing_spirv_std_dep_for_git_source_hash() { + let definition = "spirv-std v9.9.9 (https://github.com/Rust-GPU/rust-gpu#82a0f69) (*)"; + let source = SpirvSource::parse_spirv_std_source_and_version(definition); + assert_eq!( + source, + SpirvSource::Git { + url: "https://github.com/Rust-GPU/rust-gpu".to_owned(), + rev: "82a0f69".to_owned() + } ); } } From 2ec65249a9152f22f8468fa59b2af9438ba578ac Mon Sep 17 00:00:00 2001 From: Schell Carl Scivally Date: Sat, 21 Dec 2024 10:10:16 +1300 Subject: [PATCH 05/10] add extra debugging --- crates/spirv-builder-cli/src/main.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/crates/spirv-builder-cli/src/main.rs b/crates/spirv-builder-cli/src/main.rs index a18a339..496c2cc 100644 --- a/crates/spirv-builder-cli/src/main.rs +++ b/crates/spirv-builder-cli/src/main.rs @@ -93,6 +93,7 @@ fn main() { log::debug!("Calling `rust-gpu`'s `spirv-builder` library"); builder.build().unwrap() }; + log::debug!("found entry points: {entry_points:#?}"); let dir = output_dir; let mut shaders = vec![]; @@ -100,6 +101,7 @@ fn main() { ModuleResult::MultiModule(modules) => { assert!(!modules.is_empty(), "No shader modules to compile"); for (entry, filepath) in modules.into_iter() { + log::debug!("compiled {entry} {}", filepath.display()); shaders.push(ShaderModule::new(entry, filepath)); } } From 1bb88f9f2ba554413c4387099397d2864c87a24a Mon Sep 17 00:00:00 2001 From: Schell Carl Scivally Date: Sat, 21 Dec 2024 10:23:54 +1300 Subject: [PATCH 06/10] appease clippy --- crates/cargo-gpu/src/show.rs | 7 ++++--- crates/cargo-gpu/src/spirv_source.rs | 13 +++++++++---- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/crates/cargo-gpu/src/show.rs b/crates/cargo-gpu/src/show.rs index 56f8c3b..cc1e9d8 100644 --- a/crates/cargo-gpu/src/show.rs +++ b/crates/cargo-gpu/src/show.rs @@ -2,8 +2,9 @@ use crate::cache_dir; +/// Show the computed source of the spirv-std dependency. #[derive(Clone, Debug, clap::Parser)] -pub struct ShowSpirvSource { +pub struct SpirvSourceDep { /// The location of the shader-crate to inspect to determine its spirv-std dependency. #[clap(long, default_value = "./")] pub shader_crate: std::path::PathBuf, @@ -15,7 +16,7 @@ pub enum Info { /// Displays the location of the cache directory CacheDirectory, /// The source location of spirv-std - SpirvSource(ShowSpirvSource), + SpirvSource(SpirvSourceDep), } /// `cargo gpu show` @@ -34,7 +35,7 @@ impl Show { Info::CacheDirectory => { println!("{}", cache_dir().display()); } - Info::SpirvSource(ShowSpirvSource { shader_crate }) => { + Info::SpirvSource(SpirvSourceDep { shader_crate }) => { let rust_gpu_source = crate::spirv_source::SpirvSource::get_spirv_std_dep_definition(&shader_crate); println!("{rust_gpu_source}"); diff --git a/crates/cargo-gpu/src/spirv_source.rs b/crates/cargo-gpu/src/spirv_source.rs index c12d39e..233b799 100644 --- a/crates/cargo-gpu/src/spirv_source.rs +++ b/crates/cargo-gpu/src/spirv_source.rs @@ -24,7 +24,12 @@ pub enum SpirvSource { /// then the source of `rust-gpu` is `Git`. /// /// `(String, String)` is the repo source and revision hash or tag. - Git { url: String, rev: String }, + Git { + /// URL of the repository + url: String, + /// Revision or "commitsh" + rev: String, + }, /// If the shader specifies a version like: /// `spirv-std = { path = "/path/to/rust-gpu" ... }` /// then the source of `rust-gpu` is `Path`. @@ -40,9 +45,9 @@ impl core::fmt::Display for SpirvSource { )] fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { match self { - SpirvSource::CratesIO(version) => f.write_str(version), - SpirvSource::Git { url, rev } => f.write_str(&format!("{url}+{rev}")), - SpirvSource::Path((a, b)) => f.write_str(&format!("{a}+{b}")), + Self::CratesIO(version) => f.write_str(version), + Self::Git { url, rev } => f.write_str(&format!("{url}+{rev}")), + Self::Path((a, b)) => f.write_str(&format!("{a}+{b}")), } } } From feedfe1c501bb861c37146484dbf9dcb6106afa2 Mon Sep 17 00:00:00 2001 From: Schell Carl Scivally Date: Sat, 21 Dec 2024 10:50:14 +1300 Subject: [PATCH 07/10] sanitise the path for cargo tree invocation --- crates/cargo-gpu/src/main.rs | 11 +++++++++-- crates/cargo-gpu/src/spirv_source.rs | 25 ++++++++++++++++++++++--- crates/cargo-gpu/src/toml.rs | 2 +- 3 files changed, 32 insertions(+), 6 deletions(-) diff --git a/crates/cargo-gpu/src/main.rs b/crates/cargo-gpu/src/main.rs index 267fd14..1c80d66 100644 --- a/crates/cargo-gpu/src/main.rs +++ b/crates/cargo-gpu/src/main.rs @@ -78,10 +78,17 @@ fn main() { match cli.command { Command::Install(install) => { + log::debug!("installing with arguments: {install:#?}"); let (_, _) = install.run(); } - Command::Build(mut build) => build.run(), - Command::Toml(toml) => toml.run(), + Command::Build(mut build) => { + log::debug!("building with arguments: {build:#?}"); + build.run() + } + Command::Toml(toml) => { + log::debug!("building by toml file with arguments: {toml:#?}"); + toml.run() + } Command::Show(show) => show.run(), Command::DumpUsage => dump_full_usage_for_readme(), } diff --git a/crates/cargo-gpu/src/spirv_source.rs b/crates/cargo-gpu/src/spirv_source.rs index 233b799..c16cdf2 100644 --- a/crates/cargo-gpu/src/spirv_source.rs +++ b/crates/cargo-gpu/src/spirv_source.rs @@ -172,9 +172,22 @@ impl SpirvSource { /// Get the shader crate's `spirv_std = ...` definition in its `Cargo.toml` pub fn get_spirv_std_dep_definition(shader_crate_path: &std::path::PathBuf) -> Self { - log::debug!("Running `cargo tree` on {}", shader_crate_path.display()); + let cwd = std::env::current_dir().expect("no cwd"); + let exec_path = if shader_crate_path.is_absolute() { + shader_crate_path.clone() + } else { + cwd.join(shader_crate_path) + } + .canonicalize() + .expect("could not get absolute path to shader crate"); + if !exec_path.is_dir() { + log::error!("{exec_path:?} is not a directory, aborting"); + panic!("{exec_path:?} is not a directory"); + } + + log::debug!("Running `cargo tree` on {}", exec_path.display()); let output_cargo_tree = std::process::Command::new("cargo") - .current_dir(shader_crate_path) + .current_dir(&exec_path) .args(["tree", "--workspace", "--depth", "1", "--prefix", "none"]) .output() .unwrap(); @@ -190,7 +203,7 @@ impl SpirvSource { log::trace!(" found {maybe_spirv_std_def:?}"); let Some(spirv_std_def) = maybe_spirv_std_def else { - panic!("`spirv-std` not found in shader's `Cargo.toml` at {shader_crate_path:?}:\n{cargo_tree_string}"); + panic!("`spirv-std` not found in shader's `Cargo.toml` at {exec_path:?}:\n{cargo_tree_string}"); }; Self::parse_spirv_std_source_and_version(spirv_std_def) @@ -344,4 +357,10 @@ mod test { } ); } + + #[test_log::test] + fn path_sanity() { + let path = std::path::PathBuf::from("./"); + assert!(path.is_relative()); + } } diff --git a/crates/cargo-gpu/src/toml.rs b/crates/cargo-gpu/src/toml.rs index cf76f7d..8d82cde 100644 --- a/crates/cargo-gpu/src/toml.rs +++ b/crates/cargo-gpu/src/toml.rs @@ -5,7 +5,7 @@ use clap::Parser; use crate::{Cli, Command}; /// `cargo gpu toml` -#[derive(Parser)] +#[derive(Debug, Parser)] pub struct Toml { /// Path to a workspace or package Cargo.toml file. /// From f1a947b38467f29cf97265f1cf30a7cd4851d4e2 Mon Sep 17 00:00:00 2001 From: Schell Carl Scivally Date: Sat, 21 Dec 2024 11:19:10 +1300 Subject: [PATCH 08/10] don't use depth=1 for cargo tree as it misses spirv-std sometimes --- crates/cargo-gpu/src/spirv_source.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/cargo-gpu/src/spirv_source.rs b/crates/cargo-gpu/src/spirv_source.rs index c16cdf2..95fcb93 100644 --- a/crates/cargo-gpu/src/spirv_source.rs +++ b/crates/cargo-gpu/src/spirv_source.rs @@ -188,7 +188,7 @@ impl SpirvSource { log::debug!("Running `cargo tree` on {}", exec_path.display()); let output_cargo_tree = std::process::Command::new("cargo") .current_dir(&exec_path) - .args(["tree", "--workspace", "--depth", "1", "--prefix", "none"]) + .args(["tree", "--workspace", "--prefix", "none"]) .output() .unwrap(); assert!( From fc8ecfc71cd6504b67794149cd26391514af4afb Mon Sep 17 00:00:00 2001 From: Schell Carl Scivally Date: Sat, 21 Dec 2024 11:19:42 +1300 Subject: [PATCH 09/10] ensure output-dir is relative to toml when building with `toml` --- crates/cargo-gpu/src/toml.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/crates/cargo-gpu/src/toml.rs b/crates/cargo-gpu/src/toml.rs index 8d82cde..f067f5a 100644 --- a/crates/cargo-gpu/src/toml.rs +++ b/crates/cargo-gpu/src/toml.rs @@ -110,6 +110,12 @@ impl Toml { command: Command::Build(mut build), } = Cli::parse_from(parameters) { + // Ensure that the output directory is relative to the toml file + if build.output_dir.is_relative() { + let dir = path.parent().expect("no path parent"); + build.output_dir = dir.join(build.output_dir); + } + log::debug!("build: {build:?}"); build.run(); } else { From 2395dd76d0e6fb9e628c55a936e313bc9b69a469 Mon Sep 17 00:00:00 2001 From: Thomas Buckley-Houston Date: Sat, 21 Dec 2024 08:37:21 +0100 Subject: [PATCH 10/10] Fix for failing Windows build For some reason `spirv-tools-sys` only fails to build on windows when run from inside `cargo test`. Maybe it's something to do with what gets set in ENV? Also added `just` so that we have a canonical way of running CI-related tasks. --- .github/workflows/push.yaml | 11 +++++++++-- Cargo.lock | 22 ---------------------- Cargo.toml | 1 - crates/cargo-gpu/Cargo.toml | 1 - crates/cargo-gpu/src/build.rs | 8 ++++++-- crates/cargo-gpu/src/install.rs | 3 ++- crates/cargo-gpu/src/main.rs | 4 ++-- crates/cargo-gpu/src/spirv_source.rs | 8 +------- justfile | 19 +++++++++++++++++++ 9 files changed, 39 insertions(+), 38 deletions(-) create mode 100644 justfile diff --git a/.github/workflows/push.yaml b/.github/workflows/push.yaml index 4eb468e..26dca5b 100644 --- a/.github/workflows/push.yaml +++ b/.github/workflows/push.yaml @@ -28,15 +28,22 @@ jobs: steps: - uses: actions/checkout@v2 - uses: moonrepo/setup-rust@v1 + - uses: extractions/setup-just@v2 - name: Install Rust toolchain run: | rustup default stable rustup update - run: cargo test + - name: Run a full build + run: just build-shader-template + - clippy: + lints: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - uses: moonrepo/setup-rust@v1 - - run: cargo clippy -- --deny warnings + - uses: extractions/setup-just@v2 + - uses: cargo-bins/cargo-binstall@main + - run: just setup-lints + - run: just lints diff --git a/Cargo.lock b/Cargo.lock index d11c416..88ba813 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -91,7 +91,6 @@ dependencies = [ "relative-path", "serde", "serde_json", - "snafu", "spirv-builder-cli", "test-log", "toml", @@ -531,27 +530,6 @@ dependencies = [ "lazy_static", ] -[[package]] -name = "snafu" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "223891c85e2a29c3fe8fb900c1fae5e69c2e42415e3177752e8718475efa5019" -dependencies = [ - "snafu-derive", -] - -[[package]] -name = "snafu-derive" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03c3c6b7927ffe7ecaa769ee0e3994da3b8cafc8f444578982c83ecb161af917" -dependencies = [ - "heck", - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "spirv-builder-cli" version = "0.1.0" diff --git a/Cargo.toml b/Cargo.toml index 283e9ef..f8122de 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,7 +24,6 @@ log = "0.4" relative-path = "1.9.3" serde = { version = "1.0.214", features = ["derive"] } serde_json = "1.0.132" -snafu = "0.8.5" toml = "0.8.19" test-log = "0.2.16" diff --git a/crates/cargo-gpu/Cargo.toml b/crates/cargo-gpu/Cargo.toml index 67df799..e6043d1 100644 --- a/crates/cargo-gpu/Cargo.toml +++ b/crates/cargo-gpu/Cargo.toml @@ -17,7 +17,6 @@ log.workspace = true relative-path.workspace = true serde.workspace = true serde_json.workspace = true -snafu.workspace = true toml.workspace = true chrono.workspace = true http.workspace = true diff --git a/crates/cargo-gpu/src/build.rs b/crates/cargo-gpu/src/build.rs index d6c9016..d26718a 100644 --- a/crates/cargo-gpu/src/build.rs +++ b/crates/cargo-gpu/src/build.rs @@ -161,13 +161,17 @@ mod test { &format!("{}", output_dir.display()), ]; if let Cli { - command: Command::Build(mut build), + command: Command::Build(build), } = Cli::parse_from(args) { assert_eq!(shader_crate_path, build.install.shader_crate); assert_eq!(output_dir, build.output_dir); - build.run(); + // TODO: + // For some reason running a full build (`build.run()`) inside tests fails on Windows. + // The error is in the `build.rs` step of compiling `spirv-tools-sys`. It is not clear + // from the logged error what the problem is. For now we'll just run a full build + // outside the tests environment, see `justfile`'s `build-shader-template`. } else { panic!("was not a build command"); } diff --git a/crates/cargo-gpu/src/install.rs b/crates/cargo-gpu/src/install.rs index 7e79533..ca73728 100644 --- a/crates/cargo-gpu/src/install.rs +++ b/crates/cargo-gpu/src/install.rs @@ -146,7 +146,8 @@ impl Install { } } - /// Create the `spirv-builder-cli` crate. + /// Update the `Cargo.toml` file in the `spirv-builder-cli` crate so that it contains + /// the correct version of `spirv-builder-cli`. fn update_cargo_toml(contents: &str, spirv_source: &SpirvSource) -> String { let updated = contents.lines().map(|line| { if line.contains("${AUTO-REPLACE-SOURCE}") { diff --git a/crates/cargo-gpu/src/main.rs b/crates/cargo-gpu/src/main.rs index 1c80d66..364b3e1 100644 --- a/crates/cargo-gpu/src/main.rs +++ b/crates/cargo-gpu/src/main.rs @@ -83,11 +83,11 @@ fn main() { } Command::Build(mut build) => { log::debug!("building with arguments: {build:#?}"); - build.run() + build.run(); } Command::Toml(toml) => { log::debug!("building by toml file with arguments: {toml:#?}"); - toml.run() + toml.run(); } Command::Show(show) => show.run(), Command::DumpUsage => dump_full_usage_for_readme(), diff --git a/crates/cargo-gpu/src/spirv_source.rs b/crates/cargo-gpu/src/spirv_source.rs index 95fcb93..bd2f200 100644 --- a/crates/cargo-gpu/src/spirv_source.rs +++ b/crates/cargo-gpu/src/spirv_source.rs @@ -3,8 +3,6 @@ //! We do this by calling `cargo tree` inside the shader's crate to get the defined `spirv-std` //! version. Then with that we `git checkout` the `rust-gpu` repo that corresponds to that version. //! From there we can look at the source code to get the required Rust toolchain. -//! -//! This is just a test. /// The canonical `rust-gpu` URI const RUST_GPU_REPO: &str = "https://github.com/Rust-GPU/rust-gpu"; @@ -22,8 +20,6 @@ pub enum SpirvSource { /// If the shader specifies a version like: /// `spirv-std = { git = "https://github.com..." ... }` /// then the source of `rust-gpu` is `Git`. - /// - /// `(String, String)` is the repo source and revision hash or tag. Git { /// URL of the repository url: String, @@ -33,8 +29,6 @@ pub enum SpirvSource { /// If the shader specifies a version like: /// `spirv-std = { path = "/path/to/rust-gpu" ... }` /// then the source of `rust-gpu` is `Path`. - /// - /// `(String, String)` is the repo path and the version. Path((String, String)), } @@ -95,7 +89,7 @@ impl SpirvSource { crate::cache_dir().join("rust-gpu-repo").join(dir) } - /// Checkout the `rust-gpu` to the requested version. + /// Checkout the `rust-gpu` repo to the requested version. fn checkout(&self) { log::debug!( "Checking out `rust-gpu` repo at {} to {}", diff --git a/justfile b/justfile new file mode 100644 index 0000000..1f53c29 --- /dev/null +++ b/justfile @@ -0,0 +1,19 @@ +[group: 'ci'] +build-shader-template: + cargo install --path crates/cargo-gpu + cargo gpu install --shader-crate crates/shader-crate-template + cargo gpu build --shader-crate crates/shader-crate-template --output-dir test-shaders + ls -lah test-shaders + cat test-shaders/manifest.json + +[group: 'ci'] +setup-lints: + cargo binstall cargo-shear + +[group: 'ci'] +lints: + cargo clippy -- --deny warnings + cargo fmt --check + # Look for unused crates + cargo shear +