diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index af7e4221ed..f0baa11b2b 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -54,7 +54,7 @@ jobs: run: cargo test -p rustc_codegen_spirv --release --no-default-features --features "use-installed-tools" - name: workspace test (excluding examples & difftest) - run: cargo test --release --workspace --exclude "example-runner-*" --exclude "difftest*" --no-default-features --features "use-installed-tools" + run: cargo test --release --workspace --exclude "example-runner-*" --exclude "difftest*" --no-default-features --features "use-installed-tools,clap" # Examples - name: cargo check examples diff --git a/Cargo.lock b/Cargo.lock index 7e8a8aeae8..6d0220a41e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -556,7 +556,7 @@ dependencies = [ "compiletest_rs", "itertools 0.14.0", "rustc_codegen_spirv", - "rustc_codegen_spirv-target-specs", + "rustc_codegen_spirv-types", ] [[package]] @@ -2716,7 +2716,6 @@ dependencies = [ "regex", "rspirv", "rustc-demangle", - "rustc_codegen_spirv-target-specs", "rustc_codegen_spirv-types", "rustix 1.0.8", "sanitize-filename", @@ -2730,18 +2729,16 @@ dependencies = [ "tracing-tree", ] -[[package]] -name = "rustc_codegen_spirv-target-specs" -version = "0.9.0" - [[package]] name = "rustc_codegen_spirv-types" version = "0.9.0" dependencies = [ "rspirv", + "semver", "serde", "serde_json", "spirv", + "thiserror 2.0.16", ] [[package]] @@ -3097,7 +3094,6 @@ dependencies = [ "notify", "raw-string", "rustc_codegen_spirv", - "rustc_codegen_spirv-target-specs", "rustc_codegen_spirv-types", "semver", "serde", diff --git a/Cargo.toml b/Cargo.toml index 7e00acb1ed..1eb4422bb0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,7 +20,6 @@ members = [ "crates/rustc_codegen_spirv", "crates/rustc_codegen_spirv-types", - "crates/rustc_codegen_spirv-target-specs", "crates/spirv-builder", "crates/spirv-std", "crates/spirv-std/shared", @@ -50,7 +49,6 @@ spirv-std-macros = { path = "./crates/spirv-std/macros", version = "=0.9.0" } spirv-tools = { version = "0.13.0", default-features = false } rustc_codegen_spirv = { path = "./crates/rustc_codegen_spirv", version = "=0.9.0", default-features = false } rustc_codegen_spirv-types = { path = "./crates/rustc_codegen_spirv-types", version = "=0.9.0" } -rustc_codegen_spirv-target-specs = { path = "crates/rustc_codegen_spirv-target-specs", version = "=0.9.0" } # difftest libraries mirrored from difftest workspace difftest = { path = "tests/difftests/lib" } diff --git a/crates/rustc_codegen_spirv-target-specs/Cargo.toml b/crates/rustc_codegen_spirv-target-specs/Cargo.toml deleted file mode 100644 index 76e6e2c106..0000000000 --- a/crates/rustc_codegen_spirv-target-specs/Cargo.toml +++ /dev/null @@ -1,12 +0,0 @@ -[package] -name = "rustc_codegen_spirv-target-specs" -description = "target spec json files of rust-gpu for the rustc compiler" -version.workspace = true -authors.workspace = true -edition.workspace = true -license.workspace = true -repository.workspace = true - -[features] -include_str = [] -dir_path = [] diff --git a/crates/rustc_codegen_spirv-target-specs/README.md b/crates/rustc_codegen_spirv-target-specs/README.md deleted file mode 100644 index 9b0bc4d74a..0000000000 --- a/crates/rustc_codegen_spirv-target-specs/README.md +++ /dev/null @@ -1,7 +0,0 @@ -# `rustc_codegen_spirv-target-specs` - -The target spec json files of rust-gpu to hand to the rustc compiler, declaring various metadata about our codegen backend. - -## Features -* `include_str`: include target specs as string constants, for bundling with `cargo-gpu` -* `dir_path`: export a path to the target specs dir, for `spirv-builder` and `compiletest` in this repo diff --git a/crates/rustc_codegen_spirv-target-specs/src/include_str.rs b/crates/rustc_codegen_spirv-target-specs/src/include_str.rs deleted file mode 100644 index 53fba7f788..0000000000 --- a/crates/rustc_codegen_spirv-target-specs/src/include_str.rs +++ /dev/null @@ -1,75 +0,0 @@ -/// Metadata for the compile targets supported by `rust-gpu` -pub const TARGET_SPECS: &[(&str, &str)] = &[ - ( - "spirv-unknown-opengl4.0.json", - include_str!("../target-specs/spirv-unknown-opengl4.0.json"), - ), - ( - "spirv-unknown-opengl4.1.json", - include_str!("../target-specs/spirv-unknown-opengl4.1.json"), - ), - ( - "spirv-unknown-opengl4.2.json", - include_str!("../target-specs/spirv-unknown-opengl4.2.json"), - ), - ( - "spirv-unknown-opengl4.3.json", - include_str!("../target-specs/spirv-unknown-opengl4.3.json"), - ), - ( - "spirv-unknown-opengl4.5.json", - include_str!("../target-specs/spirv-unknown-opengl4.5.json"), - ), - ( - "spirv-unknown-spv1.0.json", - include_str!("../target-specs/spirv-unknown-spv1.0.json"), - ), - ( - "spirv-unknown-spv1.1.json", - include_str!("../target-specs/spirv-unknown-spv1.1.json"), - ), - ( - "spirv-unknown-spv1.2.json", - include_str!("../target-specs/spirv-unknown-spv1.2.json"), - ), - ( - "spirv-unknown-spv1.3.json", - include_str!("../target-specs/spirv-unknown-spv1.3.json"), - ), - ( - "spirv-unknown-spv1.4.json", - include_str!("../target-specs/spirv-unknown-spv1.4.json"), - ), - ( - "spirv-unknown-spv1.5.json", - include_str!("../target-specs/spirv-unknown-spv1.5.json"), - ), - ( - "spirv-unknown-spv1.6.json", - include_str!("../target-specs/spirv-unknown-spv1.6.json"), - ), - ( - "spirv-unknown-vulkan1.0.json", - include_str!("../target-specs/spirv-unknown-vulkan1.0.json"), - ), - ( - "spirv-unknown-vulkan1.1.json", - include_str!("../target-specs/spirv-unknown-vulkan1.1.json"), - ), - ( - "spirv-unknown-vulkan1.1spv1.4.json", - include_str!("../target-specs/spirv-unknown-vulkan1.1spv1.4.json"), - ), - ( - "spirv-unknown-vulkan1.2.json", - include_str!("../target-specs/spirv-unknown-vulkan1.2.json"), - ), - ( - "spirv-unknown-vulkan1.3.json", - include_str!("../target-specs/spirv-unknown-vulkan1.3.json"), - ), - ( - "spirv-unknown-vulkan1.4.json", - include_str!("../target-specs/spirv-unknown-vulkan1.4.json"), - ), -]; diff --git a/crates/rustc_codegen_spirv-target-specs/src/lib.rs b/crates/rustc_codegen_spirv-target-specs/src/lib.rs deleted file mode 100644 index b3033d9fee..0000000000 --- a/crates/rustc_codegen_spirv-target-specs/src/lib.rs +++ /dev/null @@ -1,10 +0,0 @@ -#![doc = include_str!("../README.md")] - -/// directory with all the `target-specs` jsons for our codegen backend -#[cfg(feature = "dir_path")] -pub const TARGET_SPEC_DIR_PATH: &str = concat!(env!("CARGO_MANIFEST_DIR"), "/target-specs"); - -#[cfg(feature = "include_str")] -mod include_str; -#[cfg(feature = "include_str")] -pub use include_str::TARGET_SPECS; diff --git a/crates/rustc_codegen_spirv-target-specs/target-specs/spirv-unknown-opengl4.0.json b/crates/rustc_codegen_spirv-target-specs/target-specs/spirv-unknown-opengl4.0.json deleted file mode 100644 index d76e303e2a..0000000000 --- a/crates/rustc_codegen_spirv-target-specs/target-specs/spirv-unknown-opengl4.0.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "allows-weak-linkage": false, - "arch": "spirv", - "crt-objects-fallback": "false", - "crt-static-allows-dylibs": true, - "crt-static-respected": true, - "data-layout": "e-m:e-p:32:32:32-i64:64-n8:16:32:64", - "dll-prefix": "", - "dll-suffix": ".spv.json", - "dynamic-linking": true, - "emit-debug-gdb-scripts": false, - "env": "opengl4.0", - "linker-flavor": "unix", - "linker-is-gnu": false, - "llvm-target": "spirv-unknown-opengl4.0", - "main-needs-argc-argv": false, - "metadata": { - "description": null, - "host_tools": null, - "std": null, - "tier": null - }, - "panic-strategy": "abort", - "simd-types-indirect": false, - "target-pointer-width": "32" -} diff --git a/crates/rustc_codegen_spirv-target-specs/target-specs/spirv-unknown-opengl4.1.json b/crates/rustc_codegen_spirv-target-specs/target-specs/spirv-unknown-opengl4.1.json deleted file mode 100644 index 10eaa2f6ed..0000000000 --- a/crates/rustc_codegen_spirv-target-specs/target-specs/spirv-unknown-opengl4.1.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "allows-weak-linkage": false, - "arch": "spirv", - "crt-objects-fallback": "false", - "crt-static-allows-dylibs": true, - "crt-static-respected": true, - "data-layout": "e-m:e-p:32:32:32-i64:64-n8:16:32:64", - "dll-prefix": "", - "dll-suffix": ".spv.json", - "dynamic-linking": true, - "emit-debug-gdb-scripts": false, - "env": "opengl4.1", - "linker-flavor": "unix", - "linker-is-gnu": false, - "llvm-target": "spirv-unknown-opengl4.1", - "main-needs-argc-argv": false, - "metadata": { - "description": null, - "host_tools": null, - "std": null, - "tier": null - }, - "panic-strategy": "abort", - "simd-types-indirect": false, - "target-pointer-width": "32" -} diff --git a/crates/rustc_codegen_spirv-target-specs/target-specs/spirv-unknown-opengl4.2.json b/crates/rustc_codegen_spirv-target-specs/target-specs/spirv-unknown-opengl4.2.json deleted file mode 100644 index 9a8e14bced..0000000000 --- a/crates/rustc_codegen_spirv-target-specs/target-specs/spirv-unknown-opengl4.2.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "allows-weak-linkage": false, - "arch": "spirv", - "crt-objects-fallback": "false", - "crt-static-allows-dylibs": true, - "crt-static-respected": true, - "data-layout": "e-m:e-p:32:32:32-i64:64-n8:16:32:64", - "dll-prefix": "", - "dll-suffix": ".spv.json", - "dynamic-linking": true, - "emit-debug-gdb-scripts": false, - "env": "opengl4.2", - "linker-flavor": "unix", - "linker-is-gnu": false, - "llvm-target": "spirv-unknown-opengl4.2", - "main-needs-argc-argv": false, - "metadata": { - "description": null, - "host_tools": null, - "std": null, - "tier": null - }, - "panic-strategy": "abort", - "simd-types-indirect": false, - "target-pointer-width": "32" -} diff --git a/crates/rustc_codegen_spirv-target-specs/target-specs/spirv-unknown-opengl4.3.json b/crates/rustc_codegen_spirv-target-specs/target-specs/spirv-unknown-opengl4.3.json deleted file mode 100644 index a164073671..0000000000 --- a/crates/rustc_codegen_spirv-target-specs/target-specs/spirv-unknown-opengl4.3.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "allows-weak-linkage": false, - "arch": "spirv", - "crt-objects-fallback": "false", - "crt-static-allows-dylibs": true, - "crt-static-respected": true, - "data-layout": "e-m:e-p:32:32:32-i64:64-n8:16:32:64", - "dll-prefix": "", - "dll-suffix": ".spv.json", - "dynamic-linking": true, - "emit-debug-gdb-scripts": false, - "env": "opengl4.3", - "linker-flavor": "unix", - "linker-is-gnu": false, - "llvm-target": "spirv-unknown-opengl4.3", - "main-needs-argc-argv": false, - "metadata": { - "description": null, - "host_tools": null, - "std": null, - "tier": null - }, - "panic-strategy": "abort", - "simd-types-indirect": false, - "target-pointer-width": "32" -} diff --git a/crates/rustc_codegen_spirv-target-specs/target-specs/spirv-unknown-opengl4.5.json b/crates/rustc_codegen_spirv-target-specs/target-specs/spirv-unknown-opengl4.5.json deleted file mode 100644 index 00d23b035d..0000000000 --- a/crates/rustc_codegen_spirv-target-specs/target-specs/spirv-unknown-opengl4.5.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "allows-weak-linkage": false, - "arch": "spirv", - "crt-objects-fallback": "false", - "crt-static-allows-dylibs": true, - "crt-static-respected": true, - "data-layout": "e-m:e-p:32:32:32-i64:64-n8:16:32:64", - "dll-prefix": "", - "dll-suffix": ".spv.json", - "dynamic-linking": true, - "emit-debug-gdb-scripts": false, - "env": "opengl4.5", - "linker-flavor": "unix", - "linker-is-gnu": false, - "llvm-target": "spirv-unknown-opengl4.5", - "main-needs-argc-argv": false, - "metadata": { - "description": null, - "host_tools": null, - "std": null, - "tier": null - }, - "panic-strategy": "abort", - "simd-types-indirect": false, - "target-pointer-width": "32" -} diff --git a/crates/rustc_codegen_spirv-target-specs/target-specs/spirv-unknown-spv1.0.json b/crates/rustc_codegen_spirv-target-specs/target-specs/spirv-unknown-spv1.0.json deleted file mode 100644 index b1f7f910c3..0000000000 --- a/crates/rustc_codegen_spirv-target-specs/target-specs/spirv-unknown-spv1.0.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "allows-weak-linkage": false, - "arch": "spirv", - "crt-objects-fallback": "false", - "crt-static-allows-dylibs": true, - "crt-static-respected": true, - "data-layout": "e-m:e-p:32:32:32-i64:64-n8:16:32:64", - "dll-prefix": "", - "dll-suffix": ".spv.json", - "dynamic-linking": true, - "emit-debug-gdb-scripts": false, - "env": "spv1.0", - "linker-flavor": "unix", - "linker-is-gnu": false, - "llvm-target": "spirv-unknown-spv1.0", - "main-needs-argc-argv": false, - "metadata": { - "description": null, - "host_tools": null, - "std": null, - "tier": null - }, - "panic-strategy": "abort", - "simd-types-indirect": false, - "target-pointer-width": "32" -} diff --git a/crates/rustc_codegen_spirv-target-specs/target-specs/spirv-unknown-spv1.1.json b/crates/rustc_codegen_spirv-target-specs/target-specs/spirv-unknown-spv1.1.json deleted file mode 100644 index 4319c16514..0000000000 --- a/crates/rustc_codegen_spirv-target-specs/target-specs/spirv-unknown-spv1.1.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "allows-weak-linkage": false, - "arch": "spirv", - "crt-objects-fallback": "false", - "crt-static-allows-dylibs": true, - "crt-static-respected": true, - "data-layout": "e-m:e-p:32:32:32-i64:64-n8:16:32:64", - "dll-prefix": "", - "dll-suffix": ".spv.json", - "dynamic-linking": true, - "emit-debug-gdb-scripts": false, - "env": "spv1.1", - "linker-flavor": "unix", - "linker-is-gnu": false, - "llvm-target": "spirv-unknown-spv1.1", - "main-needs-argc-argv": false, - "metadata": { - "description": null, - "host_tools": null, - "std": null, - "tier": null - }, - "panic-strategy": "abort", - "simd-types-indirect": false, - "target-pointer-width": "32" -} diff --git a/crates/rustc_codegen_spirv-target-specs/target-specs/spirv-unknown-spv1.2.json b/crates/rustc_codegen_spirv-target-specs/target-specs/spirv-unknown-spv1.2.json deleted file mode 100644 index 43a4ec9bd8..0000000000 --- a/crates/rustc_codegen_spirv-target-specs/target-specs/spirv-unknown-spv1.2.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "allows-weak-linkage": false, - "arch": "spirv", - "crt-objects-fallback": "false", - "crt-static-allows-dylibs": true, - "crt-static-respected": true, - "data-layout": "e-m:e-p:32:32:32-i64:64-n8:16:32:64", - "dll-prefix": "", - "dll-suffix": ".spv.json", - "dynamic-linking": true, - "emit-debug-gdb-scripts": false, - "env": "spv1.2", - "linker-flavor": "unix", - "linker-is-gnu": false, - "llvm-target": "spirv-unknown-spv1.2", - "main-needs-argc-argv": false, - "metadata": { - "description": null, - "host_tools": null, - "std": null, - "tier": null - }, - "panic-strategy": "abort", - "simd-types-indirect": false, - "target-pointer-width": "32" -} diff --git a/crates/rustc_codegen_spirv-target-specs/target-specs/spirv-unknown-spv1.3.json b/crates/rustc_codegen_spirv-target-specs/target-specs/spirv-unknown-spv1.3.json deleted file mode 100644 index 3903cdba51..0000000000 --- a/crates/rustc_codegen_spirv-target-specs/target-specs/spirv-unknown-spv1.3.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "allows-weak-linkage": false, - "arch": "spirv", - "crt-objects-fallback": "false", - "crt-static-allows-dylibs": true, - "crt-static-respected": true, - "data-layout": "e-m:e-p:32:32:32-i64:64-n8:16:32:64", - "dll-prefix": "", - "dll-suffix": ".spv.json", - "dynamic-linking": true, - "emit-debug-gdb-scripts": false, - "env": "spv1.3", - "linker-flavor": "unix", - "linker-is-gnu": false, - "llvm-target": "spirv-unknown-spv1.3", - "main-needs-argc-argv": false, - "metadata": { - "description": null, - "host_tools": null, - "std": null, - "tier": null - }, - "panic-strategy": "abort", - "simd-types-indirect": false, - "target-pointer-width": "32" -} diff --git a/crates/rustc_codegen_spirv-target-specs/target-specs/spirv-unknown-spv1.4.json b/crates/rustc_codegen_spirv-target-specs/target-specs/spirv-unknown-spv1.4.json deleted file mode 100644 index a645839c76..0000000000 --- a/crates/rustc_codegen_spirv-target-specs/target-specs/spirv-unknown-spv1.4.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "allows-weak-linkage": false, - "arch": "spirv", - "crt-objects-fallback": "false", - "crt-static-allows-dylibs": true, - "crt-static-respected": true, - "data-layout": "e-m:e-p:32:32:32-i64:64-n8:16:32:64", - "dll-prefix": "", - "dll-suffix": ".spv.json", - "dynamic-linking": true, - "emit-debug-gdb-scripts": false, - "env": "spv1.4", - "linker-flavor": "unix", - "linker-is-gnu": false, - "llvm-target": "spirv-unknown-spv1.4", - "main-needs-argc-argv": false, - "metadata": { - "description": null, - "host_tools": null, - "std": null, - "tier": null - }, - "panic-strategy": "abort", - "simd-types-indirect": false, - "target-pointer-width": "32" -} diff --git a/crates/rustc_codegen_spirv-target-specs/target-specs/spirv-unknown-spv1.5.json b/crates/rustc_codegen_spirv-target-specs/target-specs/spirv-unknown-spv1.5.json deleted file mode 100644 index 67a2fb375f..0000000000 --- a/crates/rustc_codegen_spirv-target-specs/target-specs/spirv-unknown-spv1.5.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "allows-weak-linkage": false, - "arch": "spirv", - "crt-objects-fallback": "false", - "crt-static-allows-dylibs": true, - "crt-static-respected": true, - "data-layout": "e-m:e-p:32:32:32-i64:64-n8:16:32:64", - "dll-prefix": "", - "dll-suffix": ".spv.json", - "dynamic-linking": true, - "emit-debug-gdb-scripts": false, - "env": "spv1.5", - "linker-flavor": "unix", - "linker-is-gnu": false, - "llvm-target": "spirv-unknown-spv1.5", - "main-needs-argc-argv": false, - "metadata": { - "description": null, - "host_tools": null, - "std": null, - "tier": null - }, - "panic-strategy": "abort", - "simd-types-indirect": false, - "target-pointer-width": "32" -} diff --git a/crates/rustc_codegen_spirv-target-specs/target-specs/spirv-unknown-spv1.6.json b/crates/rustc_codegen_spirv-target-specs/target-specs/spirv-unknown-spv1.6.json deleted file mode 100644 index 0208756e96..0000000000 --- a/crates/rustc_codegen_spirv-target-specs/target-specs/spirv-unknown-spv1.6.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "allows-weak-linkage": false, - "arch": "spirv", - "crt-objects-fallback": "false", - "crt-static-allows-dylibs": true, - "crt-static-respected": true, - "data-layout": "e-m:e-p:32:32:32-i64:64-n8:16:32:64", - "dll-prefix": "", - "dll-suffix": ".spv.json", - "dynamic-linking": true, - "emit-debug-gdb-scripts": false, - "env": "spv1.6", - "linker-flavor": "unix", - "linker-is-gnu": false, - "llvm-target": "spirv-unknown-spv1.6", - "main-needs-argc-argv": false, - "metadata": { - "description": null, - "host_tools": null, - "std": null, - "tier": null - }, - "panic-strategy": "abort", - "simd-types-indirect": false, - "target-pointer-width": "32" -} diff --git a/crates/rustc_codegen_spirv-target-specs/target-specs/spirv-unknown-vulkan1.0.json b/crates/rustc_codegen_spirv-target-specs/target-specs/spirv-unknown-vulkan1.0.json deleted file mode 100644 index 468d7e6049..0000000000 --- a/crates/rustc_codegen_spirv-target-specs/target-specs/spirv-unknown-vulkan1.0.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "allows-weak-linkage": false, - "arch": "spirv", - "crt-objects-fallback": "false", - "crt-static-allows-dylibs": true, - "crt-static-respected": true, - "data-layout": "e-m:e-p:32:32:32-i64:64-n8:16:32:64", - "dll-prefix": "", - "dll-suffix": ".spv.json", - "dynamic-linking": true, - "emit-debug-gdb-scripts": false, - "env": "vulkan1.0", - "linker-flavor": "unix", - "linker-is-gnu": false, - "llvm-target": "spirv-unknown-vulkan1.0", - "main-needs-argc-argv": false, - "metadata": { - "description": null, - "host_tools": null, - "std": null, - "tier": null - }, - "panic-strategy": "abort", - "simd-types-indirect": false, - "target-pointer-width": "32" -} diff --git a/crates/rustc_codegen_spirv-target-specs/target-specs/spirv-unknown-vulkan1.1.json b/crates/rustc_codegen_spirv-target-specs/target-specs/spirv-unknown-vulkan1.1.json deleted file mode 100644 index b75eaa7dd9..0000000000 --- a/crates/rustc_codegen_spirv-target-specs/target-specs/spirv-unknown-vulkan1.1.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "allows-weak-linkage": false, - "arch": "spirv", - "crt-objects-fallback": "false", - "crt-static-allows-dylibs": true, - "crt-static-respected": true, - "data-layout": "e-m:e-p:32:32:32-i64:64-n8:16:32:64", - "dll-prefix": "", - "dll-suffix": ".spv.json", - "dynamic-linking": true, - "emit-debug-gdb-scripts": false, - "env": "vulkan1.1", - "linker-flavor": "unix", - "linker-is-gnu": false, - "llvm-target": "spirv-unknown-vulkan1.1", - "main-needs-argc-argv": false, - "metadata": { - "description": null, - "host_tools": null, - "std": null, - "tier": null - }, - "panic-strategy": "abort", - "simd-types-indirect": false, - "target-pointer-width": "32" -} diff --git a/crates/rustc_codegen_spirv-target-specs/target-specs/spirv-unknown-vulkan1.1spv1.4.json b/crates/rustc_codegen_spirv-target-specs/target-specs/spirv-unknown-vulkan1.1spv1.4.json deleted file mode 100644 index 66eaba431b..0000000000 --- a/crates/rustc_codegen_spirv-target-specs/target-specs/spirv-unknown-vulkan1.1spv1.4.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "allows-weak-linkage": false, - "arch": "spirv", - "crt-objects-fallback": "false", - "crt-static-allows-dylibs": true, - "crt-static-respected": true, - "data-layout": "e-m:e-p:32:32:32-i64:64-n8:16:32:64", - "dll-prefix": "", - "dll-suffix": ".spv.json", - "dynamic-linking": true, - "emit-debug-gdb-scripts": false, - "env": "vulkan1.1spv1.4", - "linker-flavor": "unix", - "linker-is-gnu": false, - "llvm-target": "spirv-unknown-vulkan1.1spv1.4", - "main-needs-argc-argv": false, - "metadata": { - "description": null, - "host_tools": null, - "std": null, - "tier": null - }, - "panic-strategy": "abort", - "simd-types-indirect": false, - "target-pointer-width": "32" -} diff --git a/crates/rustc_codegen_spirv-target-specs/target-specs/spirv-unknown-vulkan1.2.json b/crates/rustc_codegen_spirv-target-specs/target-specs/spirv-unknown-vulkan1.2.json deleted file mode 100644 index 34032c502a..0000000000 --- a/crates/rustc_codegen_spirv-target-specs/target-specs/spirv-unknown-vulkan1.2.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "allows-weak-linkage": false, - "arch": "spirv", - "crt-objects-fallback": "false", - "crt-static-allows-dylibs": true, - "crt-static-respected": true, - "data-layout": "e-m:e-p:32:32:32-i64:64-n8:16:32:64", - "dll-prefix": "", - "dll-suffix": ".spv.json", - "dynamic-linking": true, - "emit-debug-gdb-scripts": false, - "env": "vulkan1.2", - "linker-flavor": "unix", - "linker-is-gnu": false, - "llvm-target": "spirv-unknown-vulkan1.2", - "main-needs-argc-argv": false, - "metadata": { - "description": null, - "host_tools": null, - "std": null, - "tier": null - }, - "panic-strategy": "abort", - "simd-types-indirect": false, - "target-pointer-width": "32" -} diff --git a/crates/rustc_codegen_spirv-target-specs/target-specs/spirv-unknown-vulkan1.3.json b/crates/rustc_codegen_spirv-target-specs/target-specs/spirv-unknown-vulkan1.3.json deleted file mode 100644 index ef4d7c2726..0000000000 --- a/crates/rustc_codegen_spirv-target-specs/target-specs/spirv-unknown-vulkan1.3.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "allows-weak-linkage": false, - "arch": "spirv", - "crt-objects-fallback": "false", - "crt-static-allows-dylibs": true, - "crt-static-respected": true, - "data-layout": "e-m:e-p:32:32:32-i64:64-n8:16:32:64", - "dll-prefix": "", - "dll-suffix": ".spv.json", - "dynamic-linking": true, - "emit-debug-gdb-scripts": false, - "env": "vulkan1.3", - "linker-flavor": "unix", - "linker-is-gnu": false, - "llvm-target": "spirv-unknown-vulkan1.3", - "main-needs-argc-argv": false, - "metadata": { - "description": null, - "host_tools": null, - "std": null, - "tier": null - }, - "panic-strategy": "abort", - "simd-types-indirect": false, - "target-pointer-width": "32" -} diff --git a/crates/rustc_codegen_spirv-target-specs/target-specs/spirv-unknown-vulkan1.4.json b/crates/rustc_codegen_spirv-target-specs/target-specs/spirv-unknown-vulkan1.4.json deleted file mode 100644 index f2b4d8ad37..0000000000 --- a/crates/rustc_codegen_spirv-target-specs/target-specs/spirv-unknown-vulkan1.4.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "allows-weak-linkage": false, - "arch": "spirv", - "crt-objects-fallback": "false", - "crt-static-allows-dylibs": true, - "crt-static-respected": true, - "data-layout": "e-m:e-p:32:32:32-i64:64-n8:16:32:64", - "dll-prefix": "", - "dll-suffix": ".spv.json", - "dynamic-linking": true, - "emit-debug-gdb-scripts": false, - "env": "vulkan1.4", - "linker-flavor": "unix", - "linker-is-gnu": false, - "llvm-target": "spirv-unknown-vulkan1.4", - "main-needs-argc-argv": false, - "metadata": { - "description": null, - "host_tools": null, - "std": null, - "tier": null - }, - "panic-strategy": "abort", - "simd-types-indirect": false, - "target-pointer-width": "32" -} diff --git a/crates/rustc_codegen_spirv-types/Cargo.toml b/crates/rustc_codegen_spirv-types/Cargo.toml index 36bd737f7e..83664a9997 100644 --- a/crates/rustc_codegen_spirv-types/Cargo.toml +++ b/crates/rustc_codegen_spirv-types/Cargo.toml @@ -12,3 +12,5 @@ spirv = { version = "0.3.0", features = ["serialize", "deserialize"] } rspirv = "0.12" serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" +semver = { version = "1.0.24", features = ["serde"] } +thiserror = "2.0.12" diff --git a/crates/rustc_codegen_spirv-types/src/lib.rs b/crates/rustc_codegen_spirv-types/src/lib.rs index c1ebdee660..336ecefbb0 100644 --- a/crates/rustc_codegen_spirv-types/src/lib.rs +++ b/crates/rustc_codegen_spirv-types/src/lib.rs @@ -3,7 +3,13 @@ pub use rspirv::spirv::Capability; mod compile_result; +mod rustc_version; +mod target; +mod target_spec; pub use compile_result::*; +pub use rustc_version::*; +pub use target::*; +pub use target_spec::*; // HACK(eddyb) allows downstream crates to access the correct version directly. pub use serde; diff --git a/crates/rustc_codegen_spirv-types/src/rustc_version.rs b/crates/rustc_codegen_spirv-types/src/rustc_version.rs new file mode 100644 index 0000000000..fdd708c8f9 --- /dev/null +++ b/crates/rustc_codegen_spirv-types/src/rustc_version.rs @@ -0,0 +1,20 @@ +use semver::Version; +use std::process::Command; + +pub fn query_rustc_version(toolchain: Option<&str>) -> std::io::Result { + let mut cmd = Command::new("rustc"); + if let Some(toolchain) = toolchain { + cmd.arg(format!("+{toolchain}")); + } + cmd.arg("--version"); + let output = cmd.output()?; + + let stdout = String::from_utf8(output.stdout).expect("stdout must be utf-8"); + let parse = |output: &str| { + let output = output.strip_prefix("rustc ")?; + let version = &output[..output.find(|c| !"0123456789.".contains(c))?]; + Version::parse(version).ok() + }; + Ok(parse(&stdout) + .unwrap_or_else(|| panic!("failed parsing `rustc --version` output `{stdout}`"))) +} diff --git a/crates/rustc_codegen_spirv-types/src/target.rs b/crates/rustc_codegen_spirv-types/src/target.rs new file mode 100644 index 0000000000..86c0bb1a0f --- /dev/null +++ b/crates/rustc_codegen_spirv-types/src/target.rs @@ -0,0 +1,70 @@ +use std::fmt::{Debug, Formatter}; +use thiserror::Error; + +pub const SPIRV_TARGET_PREFIX: &str = "spirv-unknown-"; + +/// A well-formed rust-gpu target. +/// +/// The constructors only check whether the target is well-formed, not whether it is valid. Since `spirv-builder` is +/// backwards compatible with older rust-gpu compilers, only the compiler itself knows what targets it can and cannot +/// support. This also allows adding new targets to the compiler without having to update `spirv-builder` and +/// `cargo-gpu`. +/// +/// Differentiates between a full target (e.g. `spirv-unknown-vulkan1.3`) and a target env (e.g. `vulkan1.3`). Use +/// [`Self::parse_target`] and [`Self::target`] to parse or format a full target, or use [`Self::parse_env`] and +/// [`Self::env`] when dealing with just target envs. The convenience function [`Self::parse`] accepts both targets and +/// target envs. Does not implement `Display`, since it is unclear whether the user wants a target or target env, though +/// a `Debug` implementation is provided. +#[derive(Clone)] +pub struct SpirvTarget { + target: String, +} + +impl SpirvTarget { + /// Try to parse either a full target or a target env + pub fn parse(target_or_env: &str) -> Result { + Self::parse_target(target_or_env).or_else(|_| Self::parse_env(target_or_env)) + } + + /// Parse a full target, e.g. `spirv-unknown-vulkan1.3` + pub fn parse_target(target: &str) -> Result { + let _target_env = target.strip_prefix(SPIRV_TARGET_PREFIX).ok_or_else(|| { + TargetError::NonSpirvTarget { + target: target.to_string(), + } + })?; + Ok(Self { + target: target.to_string(), + }) + } + + /// Parse a target env, e.g. `vulkan1.3` + pub fn parse_env(target_env: &str) -> Result { + Ok(Self { + target: format!("{SPIRV_TARGET_PREFIX}{target_env}"), + }) + } + + /// returns the full target, e.g. `spirv-unknown-vulkan1.3` + pub fn target(&self) -> &str { + &self.target + } + + /// returns the target env, e.g. `vulkan1.3` + pub fn env(&self) -> &str { + &self.target[SPIRV_TARGET_PREFIX.len()..] + } +} + +impl Debug for SpirvTarget { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + f.debug_tuple("Target").field(&self.target).finish() + } +} + +#[derive(Debug, Error)] +#[non_exhaustive] +pub enum TargetError { + #[error("SPIR-V target must start with `{SPIRV_TARGET_PREFIX}...`, was `{target}`")] + NonSpirvTarget { target: String }, +} diff --git a/crates/rustc_codegen_spirv-types/src/target_spec.rs b/crates/rustc_codegen_spirv-types/src/target_spec.rs new file mode 100644 index 0000000000..67d339423b --- /dev/null +++ b/crates/rustc_codegen_spirv-types/src/target_spec.rs @@ -0,0 +1,87 @@ +use crate::SpirvTarget; +use semver::Version; +use std::ffi::OsString; +use std::path::Path; + +/// Enum for different versions of target specs, to allow changing the target spec for different rust versions. +/// The version listed in the enum is always the minimum version to require said target spec, with the newest version +/// always at the top. +#[allow(non_camel_case_types)] +#[derive(Copy, Clone, Debug)] +pub enum TargetSpecVersion { + /// Introduced in `489c3ee6fd63da3ca7cf2b15e1ee709d8e078aab` in the old v2 target spec way, later ported to here. + /// remove `os: unknown`, add `crt-static-respected: true` + Rustc_1_85_0, + /// rustc 1.76 has been tested to correctly parse modern target spec jsons. + /// Some later version requires them. + /// Some earlier version fails with them (notably our 0.9.0 release). + Rustc_1_76_0, +} + +impl TargetSpecVersion { + /// Format the `--target` arg. On newer rustc versions, will create a compatible target spec json file and return + /// the absolute path to it, on older rustc versions may return the target name. + pub fn target_arg( + rustc_version: Version, + target: &SpirvTarget, + target_spec_folder: &Path, + ) -> std::io::Result { + if let Some(target_spec) = Self::from_rustc_version(rustc_version) { + std::fs::create_dir_all(target_spec_folder)?; + let spec_file = target_spec_folder.join(format!("{}.json", target.target())); + std::fs::write(&spec_file, target_spec.format_spec(target))?; + Ok(std::fs::canonicalize(spec_file)?.into_os_string()) + } else { + Ok(OsString::from(target.target())) + } + } + + /// Returns the version of the target spec required for a certain rustc version. May return `None` if the version + /// is old enough to not need target specs. + pub fn from_rustc_version(rustc_version: Version) -> Option { + if rustc_version >= Version::new(1, 85, 0) { + Some(Self::Rustc_1_85_0) + } else if rustc_version >= Version::new(1, 76, 0) { + Some(Self::Rustc_1_76_0) + } else { + None + } + } + + /// format the target spec json + pub fn format_spec(&self, target: &SpirvTarget) -> String { + let target_env = target.env(); + let extra = match self { + TargetSpecVersion::Rustc_1_85_0 => r#""crt-static-respected": true,"#, + TargetSpecVersion::Rustc_1_76_0 => r#""os": "unknown","#, + }; + format!( + r#"{{ + "allows-weak-linkage": false, + "arch": "spirv", + "crt-objects-fallback": "false", + "crt-static-allows-dylibs": true, + "data-layout": "e-m:e-p:32:32:32-i64:64-n8:16:32:64", + "dll-prefix": "", + "dll-suffix": ".spv.json", + "dynamic-linking": true, + "emit-debug-gdb-scripts": false, + "env": "{target_env}", + "linker-flavor": "unix", + "linker-is-gnu": false, + "llvm-target": "spirv-unknown-{target_env}", + "main-needs-argc-argv": false, + "metadata": {{ + "description": null, + "host_tools": null, + "std": null, + "tier": null + }}, + {extra} + "panic-strategy": "abort", + "simd-types-indirect": false, + "target-pointer-width": "32" +}}"# + ) + } +} diff --git a/crates/rustc_codegen_spirv/Cargo.toml b/crates/rustc_codegen_spirv/Cargo.toml index 8f7b880855..2357ae1f7f 100644 --- a/crates/rustc_codegen_spirv/Cargo.toml +++ b/crates/rustc_codegen_spirv/Cargo.toml @@ -62,9 +62,6 @@ tracing.workspace = true tracing-subscriber.workspace = true tracing-tree = "0.4.0" -# required for cargo gpu to resolve the needed target specs -rustc_codegen_spirv-target-specs.workspace = true - [dev-dependencies] pretty_assertions = "1.0" diff --git a/crates/spirv-builder/Cargo.toml b/crates/spirv-builder/Cargo.toml index a99bc4d884..5141408379 100644 --- a/crates/spirv-builder/Cargo.toml +++ b/crates/spirv-builder/Cargo.toml @@ -22,14 +22,11 @@ default = ["use-compiled-tools"] # Compile `rustc_codegen_spirv`, allows constructing SpirvBuilder without # explicitly passing in a path to a compiled `rustc_codegen_spirv.so` (or dll) rustc_codegen_spirv = ["dep:rustc_codegen_spirv"] -# Inclide target spec json files, allows constructing SpirvBuilder without -# explicitly passing a path to the target spec json -include-target-specs = ["dep:rustc_codegen_spirv-target-specs"] # See `rustc_codegen_spirv/Cargo.toml` for details on these features. # We add new "default" features to `use-installed-tools` and `use-compiled-tools` to keep # backwards compat with `default-features = false, features = "use-installed-tools"` setups -use-installed-tools = ["rustc_codegen_spirv", "include-target-specs", "rustc_codegen_spirv?/use-installed-tools"] -use-compiled-tools = ["rustc_codegen_spirv", "include-target-specs", "rustc_codegen_spirv?/use-compiled-tools"] +use-installed-tools = ["rustc_codegen_spirv", "rustc_codegen_spirv?/use-installed-tools"] +use-compiled-tools = ["rustc_codegen_spirv", "rustc_codegen_spirv?/use-compiled-tools"] skip-toolchain-check = ["rustc_codegen_spirv?/skip-toolchain-check"] watch = ["dep:notify"] @@ -38,7 +35,6 @@ clap = ["dep:clap"] [dependencies] rustc_codegen_spirv = { workspace = true, optional = true } rustc_codegen_spirv-types = { workspace = true } -rustc_codegen_spirv-target-specs = { workspace = true, features = ["dir_path"], optional = true } memchr = "2.4" raw-string = "0.3.5" diff --git a/crates/spirv-builder/README.md b/crates/spirv-builder/README.md index 69711c6dab..9445f74fc3 100644 --- a/crates/spirv-builder/README.md +++ b/crates/spirv-builder/README.md @@ -11,12 +11,13 @@ It takes care of pulling in the `SPIR-V` backend for Rust, `rustc_codegen_spirv` ## Example ```rust,no_run -use spirv_builder::{MetadataPrintout, SpirvBuilder}; - +# use spirv_builder::SpirvBuilder; +# fn main() -> Result<(), Box> { - SpirvBuilder::new("my_shaders", "spirv-unknown-vulkan1.1") - .print_metadata(MetadataPrintout::Full) - .build()?; + let mut builder = SpirvBuilder::new("my_shaders", "spirv-unknown-vulkan1.3"); + builder.build_script.defaults = true; + builder.build_script.env_shader_spv_path = Some(true); + builder.build()?; Ok(()) } ``` diff --git a/crates/spirv-builder/src/lib.rs b/crates/spirv-builder/src/lib.rs index 3bd3c18dec..1f07fab05f 100644 --- a/crates/spirv-builder/src/lib.rs +++ b/crates/spirv-builder/src/lib.rs @@ -73,6 +73,8 @@ pub mod cargo_cmd; mod depfile; +#[cfg(test)] +mod tests; #[cfg(feature = "watch")] mod watch; @@ -85,27 +87,20 @@ use std::env; use std::fs::File; use std::io::BufReader; use std::path::{Path, PathBuf}; -use std::process::{Command, Stdio}; +use std::process::Stdio; use thiserror::Error; -pub use rustc_codegen_spirv_types::Capability; -pub use rustc_codegen_spirv_types::{CompileResult, ModuleResult}; - #[cfg(feature = "watch")] pub use self::watch::{SpirvWatcher, SpirvWatcherError}; - -#[cfg(feature = "include-target-specs")] -pub use rustc_codegen_spirv_target_specs::TARGET_SPEC_DIR_PATH; +pub use rustc_codegen_spirv_types::*; #[derive(Debug, Error)] #[non_exhaustive] pub enum SpirvBuilderError { #[error("`target` must be set, for example `spirv-unknown-vulkan1.2`")] MissingTarget, - #[error("expected `{SPIRV_TARGET_PREFIX}...` target, found `{target}`")] - NonSpirvTarget { target: String }, - #[error("SPIR-V target `{SPIRV_TARGET_PREFIX}-{target_env}` is not supported")] - UnsupportedSpirvTargetEnv { target_env: String }, + #[error("TargetError: {0}")] + TargetError(#[from] TargetError), #[error("`path_to_crate` must be set")] MissingCratePath, #[error("crate path '{0}' does not exist")] @@ -116,19 +111,20 @@ pub enum SpirvBuilderError { MissingRustcCodegenSpirvDylib, #[error("`rustc_codegen_spirv_location` path '{0}' is not a file")] RustcCodegenSpirvDylibDoesNotExist(PathBuf), - #[error( - "Without feature `include-target-specs`, instead of setting a `target`, \ - you need to set the path of the target spec file of your particular target with `path_to_target_spec`" - )] - MissingTargetSpec, #[error("build failed")] BuildFailed, - #[error("multi-module build cannot be used with print_metadata = MetadataPrintout::Full")] - MultiModuleWithPrintMetadata, - #[error("multi-module metadata file missing")] + #[error( + "`multimodule: true` build cannot be used together with `build_script.env_shader_spv_path: true`" + )] + MultiModuleWithEnvShaderSpvPath, + #[error("some metadata file is missing")] MetadataFileMissing(#[from] std::io::Error), - #[error("unable to parse multi-module metadata file")] + #[error("unable to parse some metadata file")] MetadataFileMalformed(#[from] serde_json::Error), + #[error( + "`{ARTIFACT_SUFFIX}` artifact not found in (supposedly successful) build output.\n--- build output ---\n{stdout}" + )] + NoArtifactProduced { stdout: String }, #[error("cargo metadata error")] CargoMetadata(#[from] cargo_metadata::Error), #[cfg(feature = "watch")] @@ -136,23 +132,6 @@ pub enum SpirvBuilderError { WatchFailed(#[from] SpirvWatcherError), } -const SPIRV_TARGET_PREFIX: &str = "spirv-unknown-"; - -#[derive(Debug, PartialEq, Eq, Clone, Copy, Default, serde::Deserialize, serde::Serialize)] -#[cfg_attr(feature = "clap", derive(clap::ValueEnum))] -#[non_exhaustive] -pub enum MetadataPrintout { - /// Print no cargo metadata. - #[default] - None, - /// Print only dependency information (eg for multiple modules). - DependencyOnly, - /// Print all cargo metadata. - /// - /// Includes dependency information and spirv environment variable. - Full, -} - #[derive(Debug, PartialEq, Eq, Clone, Copy, Default, serde::Deserialize, serde::Serialize)] #[cfg_attr(feature = "clap", derive(clap::ValueEnum))] #[non_exhaustive] @@ -396,6 +375,70 @@ impl Default for ShaderCrateFeatures { } } +/// Configuration for build scripts +#[derive(Clone, Debug, Default)] +#[non_exhaustive] +pub struct BuildScriptConfig { + /// Enable this if you are using `spirv-builder` from a build script to apply some recommended default options, such + /// as [`Self::dependency_info`]. + pub defaults: bool, + + /// Print dependency information for cargo build scripts (with `cargo::rerun-if-changed={}` and such). + /// Dependency information makes cargo rerun the build script is rerun when shader source files change, thus + /// rebuilding the shader. + /// + /// Default: [`Self::defaults`] + pub dependency_info: Option, + + /// Whether to emit an env var pointing to the shader module file (via `cargo::rustc-env={}`). The name of the env + /// var is the crate name with `.spv` appended, e.g. `sky_shader.spv`. + /// Not supported together with `multimodule=true` or `.watch()`. + /// + /// Some examples on how to include the shader module in the source code: + /// * wgpu: + /// ```rust,ignore + /// let shader: ShaderModuleDescriptorPassthrough = include_spirv_raw!(env!("my_shader.spv")); + /// ``` + /// * ash + /// ```rust,ignore + /// let bytes: &[u8] = include_bytes!(env!("my_shader.spv")) + /// let words = ash::util::read_spv(&mut std::io::Cursor::new(bytes)).unwrap(); + /// ``` + /// + /// Default: `false` + pub env_shader_spv_path: Option, + + /// Forwards any warnings or errors by rustc as build script warnings (via `cargo::warning=`). Not enabling this + /// option may hide warnings if the build succeeds. + /// + /// Default: [`Self::defaults`] + pub forward_rustc_warnings: Option, + + /// Pass `--color always` to cargo to force enable colorful error messages. Particularly in build scripts, these + /// are disabled by default, even though we'll forward them to your console. Should your console not support colors, + /// then the outer cargo executing the build script will filter out all ansi escape sequences anyway, so we're free + /// to always emit them. + /// + /// Default: [`Self::defaults`] + pub cargo_color_always: Option, +} + +/// these all have the prefix `get` so the doc items link to the members, not these private fns +impl BuildScriptConfig { + fn get_dependency_info(&self) -> bool { + self.dependency_info.unwrap_or(self.defaults) + } + fn get_env_shader_spv_path(&self) -> bool { + self.env_shader_spv_path.unwrap_or(false) + } + fn get_forward_rustc_warnings(&self) -> bool { + self.forward_rustc_warnings.unwrap_or(self.defaults) + } + fn get_cargo_color_always(&self) -> bool { + self.cargo_color_always.unwrap_or(self.defaults) + } +} + #[derive(Clone, Debug, serde::Deserialize, serde::Serialize)] #[cfg_attr(feature = "clap", derive(clap::Parser))] #[non_exhaustive] @@ -410,10 +453,10 @@ pub struct SpirvBuilder { /// `--crate-type dylib`. Defaults to true if `cargo_cmd` is `None` or `Some("rustc")`. #[cfg_attr(feature = "clap", clap(skip))] pub cargo_cmd_like_rustc: Option, - /// Whether to print build.rs cargo metadata (e.g. cargo:rustc-env=var=val). Defaults to [`MetadataPrintout::None`]. - /// Within build scripts, set it to [`MetadataPrintout::DependencyOnly`] or [`MetadataPrintout::Full`] to ensure the build script is rerun on code changes. + /// Configuration for build scripts #[cfg_attr(feature = "clap", clap(skip))] - pub print_metadata: MetadataPrintout, + #[serde(skip)] + pub build_script: BuildScriptConfig, /// Build in release. Defaults to true. #[cfg_attr(feature = "clap", clap(long = "debug", default_value = "true", action = clap::ArgAction::SetFalse))] pub release: bool, @@ -461,12 +504,6 @@ pub struct SpirvBuilder { #[cfg_attr(feature = "clap", clap(skip))] pub toolchain_rustc_version: Option, - /// The path of the "target specification" file. - /// - /// For more info on "target specification" see - /// [this RFC](https://rust-lang.github.io/rfcs/0131-target-specification.html). - #[cfg_attr(feature = "clap", clap(skip))] - pub path_to_target_spec: Option, /// Set the target dir path to use for building shaders. Relative paths will be resolved /// relative to the `target` dir of the shader crate, absolute paths are used as is. /// Defaults to `spirv-builder`, resulting in the path `./target/spirv-builder`. @@ -507,7 +544,7 @@ impl Default for SpirvBuilder { path_to_crate: None, cargo_cmd: None, cargo_cmd_like_rustc: None, - print_metadata: MetadataPrintout::default(), + build_script: BuildScriptConfig::default(), release: true, target: None, deny_warnings: false, @@ -517,7 +554,6 @@ impl Default for SpirvBuilder { extensions: Vec::new(), extra_args: Vec::new(), rustc_codegen_spirv_location: None, - path_to_target_spec: None, target_dir_path: None, toolchain_overwrite: None, toolchain_rustc_version: None, @@ -538,23 +574,6 @@ impl SpirvBuilder { } } - /// Sets the path of the "target specification" file. - /// - /// For more info on "target specification" see - /// [this RFC](https://rust-lang.github.io/rfcs/0131-target-specification.html). - #[must_use] - pub fn target_spec(mut self, p: impl AsRef) -> Self { - self.path_to_target_spec = Some(p.as_ref().to_path_buf()); - self - } - - /// Whether to print build.rs cargo metadata (e.g. cargo:rustc-env=var=val). Defaults to [`MetadataPrintout::Full`]. - #[must_use] - pub fn print_metadata(mut self, v: MetadataPrintout) -> Self { - self.print_metadata = v; - self - } - #[must_use] pub fn deny_warnings(mut self, v: bool) -> Self { self.deny_warnings = v; @@ -700,23 +719,26 @@ impl SpirvBuilder { self } - /// Builds the module. If `print_metadata` is [`MetadataPrintout::Full`], you usually don't have to inspect the path - /// in the result, as the environment variable for the path to the module will already be set. + /// Builds the module pub fn build(&self) -> Result { - let metadata_file = invoke_rustc(self)?; - match self.print_metadata { - MetadataPrintout::Full | MetadataPrintout::DependencyOnly => { - leaf_deps(&metadata_file, |artifact| { - println!("cargo:rerun-if-changed={artifact}"); - }) - // Close enough - .map_err(SpirvBuilderError::MetadataFileMissing)?; + let out = self.invoke_rustc()?; + if self.build_script.get_dependency_info() { + for dep in &out.deps { + println!("cargo:rerun-if-changed={dep}"); } - MetadataPrintout::None => (), } - let metadata = self.parse_metadata_file(&metadata_file)?; - - Ok(metadata) + if self.build_script.get_env_shader_spv_path() { + match &out.compile_result.module { + ModuleResult::SingleModule(spirv_module) => { + let env_var = spirv_module.file_name().unwrap().to_str().unwrap(); + println!("cargo::rustc-env={}={}", env_var, spirv_module.display()); + } + ModuleResult::MultiModule(_) => { + Err(SpirvBuilderError::MultiModuleWithEnvShaderSpvPath)?; + } + } + } + Ok(out.compile_result) } pub(crate) fn parse_metadata_file( @@ -728,26 +750,13 @@ impl SpirvBuilder { let metadata: CompileResult = rustc_codegen_spirv_types::serde_json::from_reader(BufReader::new(metadata_contents)) .map_err(SpirvBuilderError::MetadataFileMalformed)?; - match &metadata.module { - ModuleResult::SingleModule(spirv_module) => { - assert!(!self.multimodule); - let env_var = format!( - "{}.spv", - at.file_name() - .unwrap() - .to_str() - .unwrap() - .strip_suffix(ARTIFACT_SUFFIX) - .unwrap() - ); - if self.print_metadata == MetadataPrintout::Full { - println!("cargo:rustc-env={}={}", env_var, spirv_module.display()); - } + assert_eq!( + self.multimodule, + match &metadata.module { + ModuleResult::SingleModule(_) => false, + ModuleResult::MultiModule(_) => true, } - ModuleResult::MultiModule(_) => { - assert!(self.multimodule); - } - } + ); Ok(metadata) } } @@ -803,322 +812,310 @@ fn join_checking_for_separators(strings: Vec>, sep: &str) -> St strings.join(sep) } -// Returns path to the metadata json. -fn invoke_rustc(builder: &SpirvBuilder) -> Result { - let target = builder - .target - .as_ref() - .ok_or(SpirvBuilderError::MissingTarget)?; - let path_to_crate = builder - .path_to_crate - .as_ref() - .ok_or(SpirvBuilderError::MissingCratePath)?; - { - let target_env = target.strip_prefix(SPIRV_TARGET_PREFIX).ok_or_else(|| { - SpirvBuilderError::NonSpirvTarget { - target: target.clone(), - } - })?; - // HACK(eddyb) used only to split the full list into groups. - #[allow(clippy::match_same_arms)] - match target_env { - // HACK(eddyb) hardcoded list to avoid checking if the JSON file - // for a particular target exists (and sanitizing strings for paths). - // - // FIXME(eddyb) consider moving this list, or even `target-specs`, - // into `rustc_codegen_spirv_types`'s code/source. - "spv1.0" | "spv1.1" | "spv1.2" | "spv1.3" | "spv1.4" | "spv1.5" | "spv1.6" => {} - "opengl4.0" | "opengl4.1" | "opengl4.2" | "opengl4.3" | "opengl4.5" => {} - "vulkan1.0" | "vulkan1.1" | "vulkan1.1spv1.4" | "vulkan1.2" | "vulkan1.3" - | "vulkan1.4" => {} - - _ => { - return Err(SpirvBuilderError::UnsupportedSpirvTargetEnv { - target_env: target_env.into(), - }); +pub struct RustcOutput { + pub compile_result: CompileResult, + pub deps: Vec, +} + +impl SpirvBuilder { + fn invoke_rustc(&self) -> Result { + let path_to_crate = self + .path_to_crate + .as_ref() + .ok_or(SpirvBuilderError::MissingCratePath)?; + let target; + { + let target_str = self + .target + .as_ref() + .ok_or(SpirvBuilderError::MissingTarget)?; + target = SpirvTarget::parse(target_str)?; + if !path_to_crate.is_dir() { + return Err(SpirvBuilderError::CratePathDoesntExist( + path_to_crate.clone(), + )); } } - if (builder.print_metadata == MetadataPrintout::Full) && builder.multimodule { - return Err(SpirvBuilderError::MultiModuleWithPrintMetadata); - } - if !path_to_crate.is_dir() { - return Err(SpirvBuilderError::CratePathDoesntExist( - path_to_crate.clone(), + let toolchain_rustc_version = + if let Some(toolchain_rustc_version) = &self.toolchain_rustc_version { + toolchain_rustc_version.clone() + } else { + query_rustc_version(self.toolchain_overwrite.as_deref())? + }; + + // Okay, this is a little bonkers: in a normal world, we'd have the user clone + // rustc_codegen_spirv and pass in the path to it, and then we'd invoke cargo to build it, grab + // the resulting .so, and pass it into -Z codegen-backend. But that's really gross: the user + // needs to clone rustc_codegen_spirv and tell us its path! So instead, we *directly reference + // rustc_codegen_spirv in spirv-self's Cargo.toml*, which means that it will get built + // alongside build.rs, and cargo will helpfully add it to LD_LIBRARY_PATH for us! However, + // rustc expects a full path, instead of a filename looked up via LD_LIBRARY_PATH, so we need + // to copy cargo's understanding of library lookup and find the library and its full path. + let rustc_codegen_spirv = Ok(self.rustc_codegen_spirv_location.clone()) + .transpose() + .unwrap_or_else(find_rustc_codegen_spirv)?; + if !rustc_codegen_spirv.is_file() { + return Err(SpirvBuilderError::RustcCodegenSpirvDylibDoesNotExist( + rustc_codegen_spirv, )); } - } - let toolchain_rustc_version = - if let Some(toolchain_rustc_version) = &builder.toolchain_rustc_version { - toolchain_rustc_version.clone() - } else { - query_rustc_version(builder.toolchain_overwrite.as_deref())? + let mut rustflags = vec![ + format!("-Zcodegen-backend={}", rustc_codegen_spirv.display()), + // Ensure the codegen backend is emitted in `.d` files to force Cargo + // to rebuild crates compiled with it when it changes (this used to be + // the default until https://github.com/rust-lang/rust/pull/93969). + "-Zbinary-dep-depinfo".to_string(), + "-Csymbol-mangling-version=v0".to_string(), + "-Zcrate-attr=feature(register_tool)".to_string(), + "-Zcrate-attr=register_tool(rust_gpu)".to_string(), + // HACK(eddyb) this is the same configuration that we test with, and + // ensures no unwanted surprises from e.g. `core` debug assertions. + "-Coverflow-checks=off".to_string(), + "-Cdebug-assertions=off".to_string(), + // HACK(eddyb) we need this for `core::fmt::rt::Argument::new_*` calls + // to *never* be inlined, so we can pattern-match the calls themselves. + "-Zinline-mir=off".to_string(), + // HACK(eddyb) similar to turning MIR inlining off, we also can't allow + // optimizations that drastically impact (the quality of) codegen, and + // GVN currently can lead to the memcpy-out-of-const-alloc-global-var + // pattern, even for `ScalarPair` (e.g. `return None::;`). + "-Zmir-enable-passes=-GVN".to_string(), + // HACK(eddyb) avoid ever reusing instantiations from `compiler_builtins` + // which is special-cased to turn calls to functions that never return, + // into aborts, and this applies to the panics of UB-checking helpers + // (https://github.com/rust-lang/rust/pull/122580#issuecomment-3033026194) + // but while upstream that only loses the panic message, for us it's even + // worse, as we lose the chance to remove otherwise-dead `fmt::Arguments`. + "-Zshare-generics=off".to_string(), + ]; + + // Wrapper for `env::var` that appropriately informs Cargo of the dependency. + let tracked_env_var_get = |name| { + if self.build_script.get_dependency_info() { + println!("cargo:rerun-if-env-changed={name}"); + } + env::var(name) }; - // Okay, this is a little bonkers: in a normal world, we'd have the user clone - // rustc_codegen_spirv and pass in the path to it, and then we'd invoke cargo to build it, grab - // the resulting .so, and pass it into -Z codegen-backend. But that's really gross: the user - // needs to clone rustc_codegen_spirv and tell us its path! So instead, we *directly reference - // rustc_codegen_spirv in spirv-builder's Cargo.toml*, which means that it will get built - // alongside build.rs, and cargo will helpfully add it to LD_LIBRARY_PATH for us! However, - // rustc expects a full path, instead of a filename looked up via LD_LIBRARY_PATH, so we need - // to copy cargo's understanding of library lookup and find the library and its full path. - let rustc_codegen_spirv = Ok(builder.rustc_codegen_spirv_location.clone()) - .transpose() - .unwrap_or_else(find_rustc_codegen_spirv)?; - if !rustc_codegen_spirv.is_file() { - return Err(SpirvBuilderError::RustcCodegenSpirvDylibDoesNotExist( - rustc_codegen_spirv, - )); - } - - let mut rustflags = vec![ - format!("-Zcodegen-backend={}", rustc_codegen_spirv.display()), - // Ensure the codegen backend is emitted in `.d` files to force Cargo - // to rebuild crates compiled with it when it changes (this used to be - // the default until https://github.com/rust-lang/rust/pull/93969). - "-Zbinary-dep-depinfo".to_string(), - "-Csymbol-mangling-version=v0".to_string(), - "-Zcrate-attr=feature(register_tool)".to_string(), - "-Zcrate-attr=register_tool(rust_gpu)".to_string(), - // HACK(eddyb) this is the same configuration that we test with, and - // ensures no unwanted surprises from e.g. `core` debug assertions. - "-Coverflow-checks=off".to_string(), - "-Cdebug-assertions=off".to_string(), - // HACK(eddyb) we need this for `core::fmt::rt::Argument::new_*` calls - // to *never* be inlined, so we can pattern-match the calls themselves. - "-Zinline-mir=off".to_string(), - // HACK(eddyb) similar to turning MIR inlining off, we also can't allow - // optimizations that drastically impact (the quality of) codegen, and - // GVN currently can lead to the memcpy-out-of-const-alloc-global-var - // pattern, even for `ScalarPair` (e.g. `return None::;`). - "-Zmir-enable-passes=-GVN".to_string(), - // HACK(eddyb) avoid ever reusing instantiations from `compiler_builtins` - // which is special-cased to turn calls to functions that never return, - // into aborts, and this applies to the panics of UB-checking helpers - // (https://github.com/rust-lang/rust/pull/122580#issuecomment-3033026194) - // but while upstream that only loses the panic message, for us it's even - // worse, as we lose the chance to remove otherwise-dead `fmt::Arguments`. - "-Zshare-generics=off".to_string(), - ]; - - // Wrapper for `env::var` that appropriately informs Cargo of the dependency. - let tracked_env_var_get = |name| { - if let MetadataPrintout::Full | MetadataPrintout::DependencyOnly = builder.print_metadata { - println!("cargo:rerun-if-env-changed={name}"); + let mut llvm_args = vec![]; + if self.multimodule { + llvm_args.push("--module-output=multiple".to_string()); } - env::var(name) - }; - - let mut llvm_args = vec![]; - if builder.multimodule { - llvm_args.push("--module-output=multiple".to_string()); - } - match builder.spirv_metadata { - SpirvMetadata::None => (), - SpirvMetadata::NameVariables => { - llvm_args.push("--spirv-metadata=name-variables".to_string()); + match self.spirv_metadata { + SpirvMetadata::None => (), + SpirvMetadata::NameVariables => { + llvm_args.push("--spirv-metadata=name-variables".to_string()); + } + SpirvMetadata::Full => llvm_args.push("--spirv-metadata=full".to_string()), } - SpirvMetadata::Full => llvm_args.push("--spirv-metadata=full".to_string()), - } - if builder.validator.relax_struct_store { - llvm_args.push("--relax-struct-store".to_string()); - } - if builder.validator.relax_logical_pointer { - llvm_args.push("--relax-logical-pointer".to_string()); - } - if builder.validator.relax_block_layout.unwrap_or(false) { - llvm_args.push("--relax-block-layout".to_string()); - } - if builder.validator.uniform_buffer_standard_layout { - llvm_args.push("--uniform-buffer-standard-layout".to_string()); - } - if builder.validator.scalar_block_layout { - llvm_args.push("--scalar-block-layout".to_string()); - } - if builder.validator.skip_block_layout { - llvm_args.push("--skip-block-layout".to_string()); - } - if builder.optimizer.preserve_bindings { - llvm_args.push("--preserve-bindings".to_string()); - } - let mut target_features = vec![]; - let abort_strategy = match builder.shader_panic_strategy { - ShaderPanicStrategy::SilentExit => None, - ShaderPanicStrategy::DebugPrintfThenExit { - print_inputs, - print_backtrace, - } => { - target_features.push("+ext:SPV_KHR_non_semantic_info".into()); - Some(format!( - "debug-printf{}{}", - if print_inputs { "+inputs" } else { "" }, - if print_backtrace { "+backtrace" } else { "" } - )) + if self.validator.relax_struct_store { + llvm_args.push("--relax-struct-store".to_string()); } - ShaderPanicStrategy::UNSOUND_DO_NOT_USE_UndefinedBehaviorViaUnreachable => { - Some("unreachable".into()) + if self.validator.relax_logical_pointer { + llvm_args.push("--relax-logical-pointer".to_string()); } - }; - llvm_args.extend(abort_strategy.map(|strategy| format!("--abort-strategy={strategy}"))); + if self.validator.relax_block_layout.unwrap_or(false) { + llvm_args.push("--relax-block-layout".to_string()); + } + if self.validator.uniform_buffer_standard_layout { + llvm_args.push("--uniform-buffer-standard-layout".to_string()); + } + if self.validator.scalar_block_layout { + llvm_args.push("--scalar-block-layout".to_string()); + } + if self.validator.skip_block_layout { + llvm_args.push("--skip-block-layout".to_string()); + } + if self.optimizer.preserve_bindings { + llvm_args.push("--preserve-bindings".to_string()); + } + let mut target_features = vec![]; + let abort_strategy = match self.shader_panic_strategy { + ShaderPanicStrategy::SilentExit => None, + ShaderPanicStrategy::DebugPrintfThenExit { + print_inputs, + print_backtrace, + } => { + target_features.push("+ext:SPV_KHR_non_semantic_info".into()); + Some(format!( + "debug-printf{}{}", + if print_inputs { "+inputs" } else { "" }, + if print_backtrace { "+backtrace" } else { "" } + )) + } + ShaderPanicStrategy::UNSOUND_DO_NOT_USE_UndefinedBehaviorViaUnreachable => { + Some("unreachable".into()) + } + }; + llvm_args.extend(abort_strategy.map(|strategy| format!("--abort-strategy={strategy}"))); - if let Ok(extra_codegen_args) = tracked_env_var_get("RUSTGPU_CODEGEN_ARGS") { - llvm_args.extend(extra_codegen_args.split_whitespace().map(|s| s.to_string())); - } else { - llvm_args.extend(builder.extra_args.iter().cloned()); - } + if let Ok(extra_codegen_args) = tracked_env_var_get("RUSTGPU_CODEGEN_ARGS") { + llvm_args.extend(extra_codegen_args.split_whitespace().map(|s| s.to_string())); + } else { + llvm_args.extend(self.extra_args.iter().cloned()); + } - let llvm_args = join_checking_for_separators(llvm_args, " "); - if !llvm_args.is_empty() { - rustflags.push(["-Cllvm-args=", &llvm_args].concat()); - } + let llvm_args = join_checking_for_separators(llvm_args, " "); + if !llvm_args.is_empty() { + rustflags.push(["-Cllvm-args=", &llvm_args].concat()); + } - target_features.extend(builder.capabilities.iter().map(|cap| format!("+{cap:?}"))); - target_features.extend(builder.extensions.iter().map(|ext| format!("+ext:{ext}"))); - let target_features = join_checking_for_separators(target_features, ","); - if !target_features.is_empty() { - rustflags.push(["-Ctarget-feature=", &target_features].concat()); - } + target_features.extend(self.capabilities.iter().map(|cap| format!("+{cap:?}"))); + target_features.extend(self.extensions.iter().map(|ext| format!("+ext:{ext}"))); + let target_features = join_checking_for_separators(target_features, ","); + if !target_features.is_empty() { + rustflags.push(["-Ctarget-feature=", &target_features].concat()); + } - if builder.deny_warnings { - rustflags.push("-Dwarnings".to_string()); - } + if self.deny_warnings { + rustflags.push("-Dwarnings".to_string()); + } - if let Ok(extra_rustflags) = tracked_env_var_get("RUSTGPU_RUSTFLAGS") { - rustflags.extend(extra_rustflags.split_whitespace().map(|s| s.to_string())); - } + if let Ok(extra_rustflags) = tracked_env_var_get("RUSTGPU_RUSTFLAGS") { + rustflags.extend(extra_rustflags.split_whitespace().map(|s| s.to_string())); + } - let target_dir_path = builder - .target_dir_path - .clone() - .unwrap_or_else(|| PathBuf::from("spirv-builder")); - let target_dir = if target_dir_path.is_absolute() { - target_dir_path - } else { - let metadata = cargo_metadata::MetadataCommand::new() - .current_dir(path_to_crate) - .exec()?; - metadata - .target_directory - .into_std_path_buf() - .join(target_dir_path) - }; + let target_dir_path = self + .target_dir_path + .clone() + .unwrap_or_else(|| PathBuf::from("spirv-self")); + let target_dir = if target_dir_path.is_absolute() { + target_dir_path + } else { + let metadata = cargo_metadata::MetadataCommand::new() + .current_dir(path_to_crate) + .exec()?; + metadata + .target_directory + .into_std_path_buf() + .join(target_dir_path) + }; - let mut cargo = cargo_cmd::CargoCmd::new(); - if let Some(toolchain) = &builder.toolchain_overwrite { - cargo.arg(format!("+{toolchain}")); - } + let mut cargo = cargo_cmd::CargoCmd::new(); + if let Some(toolchain) = &self.toolchain_overwrite { + cargo.arg(format!("+{toolchain}")); + } - let cargo_cmd = builder.cargo_cmd.as_ref().map_or("rustc", |s| s.as_str()); - let cargo_cmd_like_rustc = builder.cargo_cmd_like_rustc.unwrap_or(cargo_cmd == "rustc"); - let profile = if builder.release { "release" } else { "dev" }; - cargo.args([ - cargo_cmd, - "--lib", - "--message-format=json-render-diagnostics", - "-Zbuild-std=core", - "-Zbuild-std-features=compiler-builtins-mem", - "--profile", - profile, - ]); - if cargo_cmd_like_rustc { - // About `crate-type`: We use it to determine whether the crate needs to be linked into shaders. For `rlib`, - // we're emitting regular rust libraries as is expected. For `dylib` or `cdylib`, we're linking all `rlib`s - // together, legalize them in many passes and emit a final `*.spv` file. Quirk: If you depend on a crate - // that has crate-type `dylib`, we also link it, and it will fail if it has no shaders, which may not be - // desired. (Gathered from reading source code and experimenting, @firestar99) - cargo.args(["--crate-type", "dylib"]); - } + let cargo_cmd = self.cargo_cmd.as_ref().map_or("rustc", |s| s.as_str()); + let cargo_cmd_like_rustc = self.cargo_cmd_like_rustc.unwrap_or(cargo_cmd == "rustc"); + let profile = if self.release { "release" } else { "dev" }; + cargo.args([ + cargo_cmd, + "--lib", + "--message-format=json-render-diagnostics", + "-Zbuild-std=core", + "-Zbuild-std-features=compiler-builtins-mem", + "--profile", + profile, + ]); + if cargo_cmd_like_rustc { + // About `crate-type`: We use it to determine whether the crate needs to be linked into shaders. For `rlib`, + // we're emitting regular rust libraries as is expected. For `dylib` or `cdylib`, we're linking all `rlib`s + // together, legalize them in many passes and emit a final `*.spv` file. Quirk: If you depend on a crate + // that has crate-type `dylib`, we also link it, and it will fail if it has no shaders, which may not be + // desired. (Gathered from reading source code and experimenting, @firestar99) + cargo.args(["--crate-type", "dylib"]); + } - if let Ok(extra_cargoflags) = tracked_env_var_get("RUSTGPU_CARGOFLAGS") { - cargo.args(extra_cargoflags.split_whitespace()); - } + if let Ok(extra_cargoflags) = tracked_env_var_get("RUSTGPU_CARGOFLAGS") { + cargo.args(extra_cargoflags.split_whitespace()); + } - // FIXME(eddyb) consider moving `target-specs` into `rustc_codegen_spirv_types`. - // FIXME(eddyb) consider the `RUST_TARGET_PATH` env var alternative. + let target_spec_dir = target_dir.join("target-specs"); + let target = + TargetSpecVersion::target_arg(toolchain_rustc_version, &target, &target_spec_dir)?; + cargo.arg("--target").arg(target); - // NOTE(firestar99) rustc 1.76 has been tested to correctly parse modern - // target_spec jsons, some later version requires them, some earlier - // version fails with them (notably our 0.9.0 release) - if toolchain_rustc_version >= Version::new(1, 76, 0) { - let path_opt = builder.path_to_target_spec.clone(); - let path; - #[cfg(feature = "include-target-specs")] - { - path = path_opt - .unwrap_or_else(|| PathBuf::from(format!("{TARGET_SPEC_DIR_PATH}/{target}.json"))); + if !self.shader_crate_features.default_features { + cargo.arg("--no-default-features"); } - #[cfg(not(feature = "include-target-specs"))] - { - path = path_opt.ok_or(SpirvBuilderError::MissingTargetSpec)?; + + if !self.shader_crate_features.features.is_empty() { + cargo + .arg("--features") + .arg(self.shader_crate_features.features.join(",")); } - cargo.arg("--target").arg(path); - } else { - cargo.arg("--target").arg(target); - } - if !builder.shader_crate_features.default_features { - cargo.arg("--no-default-features"); - } + cargo.arg("--target-dir").arg(target_dir); - if !builder.shader_crate_features.features.is_empty() { - cargo - .arg("--features") - .arg(builder.shader_crate_features.features.join(",")); - } + // Args for warning and error forwarding + if self.build_script.get_forward_rustc_warnings() { + // Quiet to remove all the status messages and only emit errors and warnings + cargo.args(["--quiet"]); + } + if self.build_script.get_cargo_color_always() { + // Always emit color, since the outer cargo will remove ascii escape sequences if color is turned off + cargo.args(["--color", "always"]); + } - cargo.arg("--target-dir").arg(target_dir); + // NOTE(eddyb) this used to be just `RUSTFLAGS` but at some point Cargo + // added a separate environment variable using `\x1f` instead of spaces, + // which allows us to have spaces within individual `rustc` flags. + cargo.env( + "CARGO_ENCODED_RUSTFLAGS", + join_checking_for_separators(rustflags, "\x1f"), + ); - // NOTE(eddyb) this used to be just `RUSTFLAGS` but at some point Cargo - // added a separate environment variable using `\x1f` instead of spaces, - // which allows us to have spaces within individual `rustc` flags. - cargo.env( - "CARGO_ENCODED_RUSTFLAGS", - join_checking_for_separators(rustflags, "\x1f"), - ); + // NOTE(eddyb) there's no parallelism to take advantage of multiple CGUs, + // and inter-CGU duplication can be wasteful, so this forces 1 CGU for now. + let profile_in_env_var = profile.replace('-', "_").to_ascii_uppercase(); + let num_cgus = 1; + cargo.env( + format!("CARGO_PROFILE_{profile_in_env_var}_CODEGEN_UNITS"), + num_cgus.to_string(), + ); - // NOTE(eddyb) there's no parallelism to take advantage of multiple CGUs, - // and inter-CGU duplication can be wasteful, so this forces 1 CGU for now. - let profile_in_env_var = profile.replace('-', "_").to_ascii_uppercase(); - let num_cgus = 1; - cargo.env( - format!("CARGO_PROFILE_{profile_in_env_var}_CODEGEN_UNITS"), - num_cgus.to_string(), - ); + if !self.build_script.get_forward_rustc_warnings() { + cargo.stderr(Stdio::inherit()); + } + cargo.current_dir(path_to_crate); + log::debug!("building shaders with `{cargo:?}`"); + let build = cargo.output().expect("failed to execute cargo build"); + + if self.build_script.get_forward_rustc_warnings() { + let stderr = String::from_utf8(build.stderr).unwrap(); + for line in stderr.lines() { + println!("cargo::warning={line}"); + } + } - cargo.stderr(Stdio::inherit()).current_dir(path_to_crate); - log::debug!("building shaders with `{cargo:?}`"); - let build = cargo.output().expect("failed to execute cargo build"); - - // `get_last_artifact` has the side-effect of printing invalid lines, so - // we do that even in case of an error, to let through any useful messages - // that ended up on stdout instead of stderr. - let stdout = String::from_utf8(build.stdout).unwrap(); - if build.status.success() { - get_sole_artifact(&stdout).ok_or_else(|| { - eprintln!("--- build output ---\n{stdout}"); - panic!( - "`{ARTIFACT_SUFFIX}` artifact not found in (supposedly successful) build output (see above). Verify that `crate-type` is set correctly" - ); - }) - } else { - Err(SpirvBuilderError::BuildFailed) + // `get_last_artifact` has the side-effect of printing invalid lines, so + // we do that even in case of an error, to let through any useful messages + // that ended up on stdout instead of stderr. + let stdout = String::from_utf8(build.stdout).unwrap(); + if build.status.success() { + let metadata_file = get_sole_artifact(&stdout) + .ok_or(SpirvBuilderError::NoArtifactProduced { stdout })?; + let compile_result = self.parse_metadata_file(&metadata_file)?; + let mut deps = Vec::new(); + leaf_deps(&metadata_file, |artifact| { + deps.push(RawString::from(artifact)); + }) + .map_err(SpirvBuilderError::MetadataFileMissing)?; + Ok(RustcOutput { + compile_result, + deps, + }) + } else { + Err(SpirvBuilderError::BuildFailed) + } } } -#[derive(Deserialize)] -struct RustcOutput { - reason: String, - filenames: Option>, -} - const ARTIFACT_SUFFIX: &str = ".spv.json"; fn get_sole_artifact(out: &str) -> Option { + #[derive(Deserialize)] + struct RustcLine { + reason: String, + filenames: Option>, + } + let mut last_compiler_artifact = None; for line in out.lines() { - let Ok(msg) = serde_json::from_str::(line) else { + let Ok(msg) = serde_json::from_str::(line) else { // Pass through invalid lines println!("{line}"); continue; @@ -1169,21 +1166,3 @@ fn leaf_deps(artifact: &Path, mut handle: impl FnMut(&RawStr)) -> std::io::Resul recurse(&deps_map, artifact.to_str().unwrap().into(), &mut handle); Ok(()) } - -pub fn query_rustc_version(toolchain: Option<&str>) -> std::io::Result { - let mut cmd = Command::new("rustc"); - if let Some(toolchain) = toolchain { - cmd.arg(format!("+{toolchain}")); - } - cmd.arg("--version"); - let output = cmd.output()?; - - let stdout = String::from_utf8(output.stdout).expect("stdout must be utf-8"); - let parse = |output: &str| { - let output = output.strip_prefix("rustc ")?; - let version = &output[..output.find(|c| !"0123456789.".contains(c))?]; - Version::parse(version).ok() - }; - Ok(parse(&stdout) - .unwrap_or_else(|| panic!("failed parsing `rustc --version` output `{stdout}`"))) -} diff --git a/crates/spirv-builder/src/tests.rs b/crates/spirv-builder/src/tests.rs new file mode 100644 index 0000000000..1550a357ba --- /dev/null +++ b/crates/spirv-builder/src/tests.rs @@ -0,0 +1,20 @@ +#[cfg(feature = "clap")] +mod clap { + pub use crate::*; + use clap::Parser; + + /// look at the output of this test to see what `--help` prints + #[test] + fn test_clap_help() { + // any malformed clap declarations should panic within clap's parse + match SpirvBuilder::try_parse_from(["", "--help"]) { + Ok(_) => panic!("`--help` should make clap return an error"), + Err(e) => { + let e = e.to_string(); + println!("{}", e); + // sanity check help + assert!(e.contains("--target")); + } + }; + } +} diff --git a/crates/spirv-builder/src/watch.rs b/crates/spirv-builder/src/watch.rs index 08d468eff5..51f0be3af9 100644 --- a/crates/spirv-builder/src/watch.rs +++ b/crates/spirv-builder/src/watch.rs @@ -1,7 +1,7 @@ -use crate::{SpirvBuilder, SpirvBuilderError, leaf_deps}; +use crate::{SpirvBuilder, SpirvBuilderError}; use notify::{Event, RecommendedWatcher, RecursiveMode, Watcher}; +use raw_string::RawStr; use rustc_codegen_spirv_types::CompileResult; -use std::path::Path; use std::sync::mpsc::TryRecvError; use std::{ collections::HashSet, @@ -55,7 +55,7 @@ impl SpirvWatcher { .as_ref() .ok_or(SpirvBuilderError::MissingCratePath)? .clone(); - if !matches!(builder.print_metadata, crate::MetadataPrintout::None) { + if builder.build_script.get_env_shader_spv_path() { return Err(SpirvWatcherError::WatchWithPrintMetadata.into()); } @@ -124,10 +124,9 @@ impl SpirvWatcher { } let result = (|| { - let metadata_file = crate::invoke_rustc(&self.builder)?; - let result = self.builder.parse_metadata_file(&metadata_file)?; - self.watch_leaf_deps(&metadata_file)?; - Ok(result) + let out = self.builder.invoke_rustc()?; + self.watch_leaf_deps(out.deps.iter().map(|d| d.as_ref())); + Ok(out.compile_result) })(); match result { Ok(result) => { @@ -155,16 +154,15 @@ impl SpirvWatcher { } } - fn watch_leaf_deps(&mut self, watch_path: &Path) -> Result<(), SpirvBuilderError> { - leaf_deps(watch_path, |artifact| { - let path = artifact.to_path().unwrap(); + fn watch_leaf_deps<'a>(&mut self, deps: impl Iterator) { + for dep in deps { + let path = dep.to_path().unwrap(); if self.watched_paths.insert(path.to_owned()) && let Err(err) = self.watcher.watch(path, RecursiveMode::NonRecursive) { - log::error!("files of cargo dependencies are not valid: {err}"); + log::error!("failed to watch `{}`: {err}", path.display()); } - }) - .map_err(SpirvBuilderError::MetadataFileMissing) + } } } diff --git a/examples/multibuilder/src/main.rs b/examples/multibuilder/src/main.rs index e694b72ee3..e64e254f3a 100644 --- a/examples/multibuilder/src/main.rs +++ b/examples/multibuilder/src/main.rs @@ -1,13 +1,11 @@ -use spirv_builder::{MetadataPrintout, SpirvBuilder}; +use spirv_builder::SpirvBuilder; fn main() { - let result = SpirvBuilder::new( + let mut builder = SpirvBuilder::new( concat!(env!("CARGO_MANIFEST_DIR"), "/../shaders/sky-shader"), "spirv-unknown-spv1.3", - ) - .print_metadata(MetadataPrintout::DependencyOnly) - .multimodule(true) - .build() - .unwrap(); + ); + builder.multimodule = true; + let result = builder.build().unwrap(); println!("{result:#?}"); } diff --git a/examples/runners/ash/src/main.rs b/examples/runners/ash/src/main.rs index 7f97c281ad..a62d58709f 100644 --- a/examples/runners/ash/src/main.rs +++ b/examples/runners/ash/src/main.rs @@ -78,7 +78,7 @@ use ash::util::read_spv; use clap::{Parser, ValueEnum}; use raw_window_handle::HasDisplayHandle as _; use shared::ShaderConstants; -use spirv_builder::{MetadataPrintout, SpirvBuilder}; +use spirv_builder::SpirvBuilder; use std::{ fs::File, path::PathBuf, @@ -259,7 +259,6 @@ pub fn compile_shaders(shader: &RustGPUShader) -> anyhow::Result> { .collect::(); let compile_result = SpirvBuilder::new(crate_path, "spirv-unknown-vulkan1.3") - .print_metadata(MetadataPrintout::None) .shader_panic_strategy(spirv_builder::ShaderPanicStrategy::DebugPrintfThenExit { print_inputs: true, print_backtrace: true, diff --git a/examples/runners/wgpu/builder/src/main.rs b/examples/runners/wgpu/builder/src/main.rs index ba94e42f64..5f91cdb293 100644 --- a/examples/runners/wgpu/builder/src/main.rs +++ b/examples/runners/wgpu/builder/src/main.rs @@ -1,18 +1,18 @@ -use spirv_builder::{MetadataPrintout, SpirvBuilder}; +use spirv_builder::SpirvBuilder; use std::env; use std::error::Error; use std::fs; -use std::path::Path; +use std::path::{Path, PathBuf}; fn build_shader(path_to_crate: &str, codegen_names: bool) -> Result<(), Box> { - let builder_dir = &Path::new(env!("CARGO_MANIFEST_DIR")); - let path_to_crate = builder_dir.join(path_to_crate); - let result = SpirvBuilder::new(path_to_crate, "spirv-unknown-vulkan1.1") - .print_metadata(MetadataPrintout::Full) - // Give this spirv-builder a unique target dir, so that rebuilding android and the main wgpu app's target dir - // don't clash and break each other's incremental - .target_dir_path("example-runner-wgpu-builder") - .build()?; + let path_to_crate = Path::new(env!("CARGO_MANIFEST_DIR")).join(path_to_crate); + let mut builder = SpirvBuilder::new(path_to_crate, "spirv-unknown-vulkan1.1"); + builder.build_script.defaults = true; + builder.build_script.env_shader_spv_path = Some(true); + // Give this spirv-builder a unique target dir, so that rebuilding android and the main wgpu app's target dir + // don't clash and break each other's incremental + builder.target_dir_path = Some(PathBuf::from("example-runner-wgpu-builder")); + let result = builder.build()?; if codegen_names { let out_dir = env::var_os("OUT_DIR").unwrap(); let dest_path = Path::new(&out_dir).join("entry_points.rs"); diff --git a/examples/runners/wgpu/src/lib.rs b/examples/runners/wgpu/src/lib.rs index 7faa69d89b..f95db5eb87 100644 --- a/examples/runners/wgpu/src/lib.rs +++ b/examples/runners/wgpu/src/lib.rs @@ -124,7 +124,7 @@ fn maybe_watch( ) -> CompiledShaderModules { #[cfg(not(any(target_os = "android", target_arch = "wasm32")))] { - use spirv_builder::{CompileResult, MetadataPrintout, SpirvBuilder}; + use spirv_builder::{CompileResult, SpirvBuilder}; use std::path::PathBuf; let crate_name = match options.shader { @@ -142,7 +142,6 @@ fn maybe_watch( let has_debug_printf = options.force_spirv_passthru; let builder = SpirvBuilder::new(crate_path, "spirv-unknown-vulkan1.1") - .print_metadata(MetadataPrintout::None) .shader_panic_strategy(if has_debug_printf { spirv_builder::ShaderPanicStrategy::DebugPrintfThenExit { print_inputs: true, diff --git a/tests/compiletests/Cargo.toml b/tests/compiletests/Cargo.toml index 9ea4a4ce46..8b88c9211b 100644 --- a/tests/compiletests/Cargo.toml +++ b/tests/compiletests/Cargo.toml @@ -16,7 +16,7 @@ use-compiled-tools = ["rustc_codegen_spirv/use-compiled-tools"] [dependencies] compiletest = { version = "0.11.2", package = "compiletest_rs" } rustc_codegen_spirv = { workspace = true } -rustc_codegen_spirv-target-specs = { workspace = true, features = ["dir_path"] } +rustc_codegen_spirv-types = { workspace = true } clap = { version = "4", features = ["derive"] } itertools = "0.14.0" diff --git a/tests/compiletests/src/main.rs b/tests/compiletests/src/main.rs index 843f9d9ea7..abe325d8b6 100644 --- a/tests/compiletests/src/main.rs +++ b/tests/compiletests/src/main.rs @@ -1,6 +1,7 @@ use clap::Parser; use itertools::Itertools as _; -use rustc_codegen_spirv_target_specs::TARGET_SPEC_DIR_PATH; +use rustc_codegen_spirv_types::{SpirvTarget, TargetSpecVersion, query_rustc_version}; +use std::ffi::OsString; use std::{ env, io, path::{Path, PathBuf}, @@ -28,12 +29,6 @@ impl Opt { } } -const SPIRV_TARGET_PREFIX: &str = "spirv-unknown-"; - -fn target_spec_json(target: &str) -> String { - format!("{TARGET_SPEC_DIR_PATH}/{target}.json") -} - #[derive(Copy, Clone)] enum DepKind { SpirvLib, @@ -48,9 +43,9 @@ impl DepKind { } } - fn target_dir_suffix(self, target: &str) -> String { + fn target_dir_suffix(self, target: &SpirvTarget) -> String { match self { - Self::SpirvLib => format!("{target}/debug/deps"), + Self::SpirvLib => format!("{}/debug/deps", target.target()), Self::ProcMacro => "debug/deps".into(), } } @@ -59,6 +54,10 @@ impl DepKind { fn main() { let opt = Opt::parse(); + // Pull in rustc_codegen_spirv as a dynamic library in the same way + // spirv-builder does. + let codegen_backend_path = find_rustc_codegen_spirv(); + let tests_dir = PathBuf::from(env!("CARGO_MANIFEST_DIR")); let workspace_root = tests_dir.parent().unwrap().parent().unwrap(); let original_target_dir = workspace_root.join("target"); @@ -72,10 +71,6 @@ fn main() { std::env::set_current_dir(tests_dir).unwrap(); let tests_dir = PathBuf::from(""); - // Pull in rustc_codegen_spirv as a dynamic library in the same way - // spirv-builder does. - let codegen_backend_path = find_rustc_codegen_spirv(); - let runner = Runner { opt, tests_dir, @@ -161,8 +156,8 @@ impl Runner { println!("Testing env: {stage_id}\n"); - let target = format!("{SPIRV_TARGET_PREFIX}{env}"); - let libs = build_deps(&self.deps_target_dir, &self.codegen_backend_path, &target); + let target = SpirvTarget::parse(env).unwrap(); + let libs = self.build_deps(&target); let mut flags = test_rustc_flags( &self.codegen_backend_path, &libs, @@ -181,7 +176,7 @@ impl Runner { stage_id, target_rustcflags: Some(flags), mode: mode.parse().expect("Invalid mode"), - target: target_spec_json(&target), + target: self.target_spec_json(&target).into_string().unwrap(), src_base: self.tests_dir.join(mode), build_base: self.compiletest_build_dir.clone(), bless: self.opt.bless, @@ -194,90 +189,86 @@ impl Runner { compiletest::run_tests(&config); } } -} - -/// Runs the processes needed to build `spirv-std` & other deps. -fn build_deps(deps_target_dir: &Path, codegen_backend_path: &Path, target: &str) -> TestDeps { - // Build compiletests-deps-helper - std::process::Command::new("cargo") - .args([ - "build", - "-p", - "compiletests-deps-helper", - "-Zbuild-std=core", - "-Zbuild-std-features=compiler-builtins-mem", - &*format!("--target={}", target_spec_json(target)), - ]) - .arg("--target-dir") - .arg(deps_target_dir) - .env("RUSTFLAGS", rust_flags(codegen_backend_path)) - .stderr(std::process::Stdio::inherit()) - .stdout(std::process::Stdio::inherit()) - .status() - .and_then(map_status_to_result) - .unwrap(); - - let compiler_builtins = find_lib( - deps_target_dir, - "compiler_builtins", - DepKind::SpirvLib, - target, - ); - let core = find_lib(deps_target_dir, "core", DepKind::SpirvLib, target); - let spirv_std = find_lib(deps_target_dir, "spirv_std", DepKind::SpirvLib, target); - let glam = find_lib(deps_target_dir, "glam", DepKind::SpirvLib, target); - let spirv_std_macros = find_lib( - deps_target_dir, - "spirv_std_macros", - DepKind::ProcMacro, - target, - ); - let all_libs = [ - &compiler_builtins, - &core, - &spirv_std, - &glam, - &spirv_std_macros, - ]; - if all_libs.iter().any(|r| r.is_err()) { - // FIXME(eddyb) `missing_count` should always be `0` anyway. - // FIXME(eddyb) use `--message-format=json-render-diagnostics` to - // avoid caring about duplicates (or search within files at all). - let missing_count = all_libs - .iter() - .filter(|r| matches!(r, Err(FindLibError::Missing))) - .count(); - let duplicate_count = all_libs - .iter() - .filter(|r| matches!(r, Err(FindLibError::Duplicate))) - .count(); - eprintln!( - "warning: cleaning deps ({missing_count} missing libs, {duplicate_count} duplicated libs)" - ); - clean_deps(deps_target_dir); - build_deps(deps_target_dir, codegen_backend_path, target) - } else { - TestDeps { - core: core.ok().unwrap(), - glam: glam.ok().unwrap(), - compiler_builtins: compiler_builtins.ok().unwrap(), - spirv_std: spirv_std.ok().unwrap(), - spirv_std_macros: spirv_std_macros.ok().unwrap(), + /// Runs the processes needed to build `spirv-std` & other deps. + fn build_deps(&self, target: &SpirvTarget) -> TestDeps { + // Build compiletests-deps-helper + std::process::Command::new("cargo") + .args([ + "build", + "-p", + "compiletests-deps-helper", + "-Zbuild-std=core", + "-Zbuild-std-features=compiler-builtins-mem", + "--target", + ]) + .arg(self.target_spec_json(target)) + .arg("--target-dir") + .arg(&self.deps_target_dir) + .env("RUSTFLAGS", rust_flags(&self.codegen_backend_path)) + .stderr(std::process::Stdio::inherit()) + .stdout(std::process::Stdio::inherit()) + .status() + .and_then(map_status_to_result) + .unwrap(); + + let compiler_builtins = self.find_lib("compiler_builtins", DepKind::SpirvLib, target); + let core = self.find_lib("core", DepKind::SpirvLib, target); + let spirv_std = self.find_lib("spirv_std", DepKind::SpirvLib, target); + let glam = self.find_lib("glam", DepKind::SpirvLib, target); + let spirv_std_macros = self.find_lib("spirv_std_macros", DepKind::ProcMacro, target); + + let all_libs = [ + &compiler_builtins, + &core, + &spirv_std, + &glam, + &spirv_std_macros, + ]; + if all_libs.iter().any(|r| r.is_err()) { + // FIXME(eddyb) `missing_count` should always be `0` anyway. + // FIXME(eddyb) use `--message-format=json-render-diagnostics` to + // avoid caring about duplicates (or search within files at all). + let missing_count = all_libs + .iter() + .filter(|r| matches!(r, Err(FindLibError::Missing))) + .count(); + let duplicate_count = all_libs + .iter() + .filter(|r| matches!(r, Err(FindLibError::Duplicate))) + .count(); + eprintln!( + "warning: cleaning deps ({missing_count} missing libs, {duplicate_count} duplicated libs)" + ); + self.clean_deps(); + self.build_deps(target) + } else { + TestDeps { + core: core.ok().unwrap(), + glam: glam.ok().unwrap(), + compiler_builtins: compiler_builtins.ok().unwrap(), + spirv_std: spirv_std.ok().unwrap(), + spirv_std_macros: spirv_std_macros.ok().unwrap(), + } } } -} -fn clean_deps(deps_target_dir: &Path) { - std::process::Command::new("cargo") - .arg("clean") - .arg("--target-dir") - .arg(deps_target_dir) - .stderr(std::process::Stdio::inherit()) - .stdout(std::process::Stdio::inherit()) - .status() - .and_then(map_status_to_result) - .unwrap(); + fn clean_deps(&self) { + std::process::Command::new("cargo") + .arg("clean") + .arg("--target-dir") + .arg(&self.deps_target_dir) + .stderr(std::process::Stdio::inherit()) + .stdout(std::process::Stdio::inherit()) + .status() + .and_then(map_status_to_result) + .unwrap(); + } + + fn target_spec_json(&self, target: &SpirvTarget) -> OsString { + let rustc_version = query_rustc_version(None).unwrap(); + TargetSpecVersion::target_arg(rustc_version, target, &self.deps_target_dir).unwrap() + } } enum FindLibError { @@ -285,49 +276,53 @@ enum FindLibError { Duplicate, } -/// Attempt find the rlib that matches `base`, if multiple rlibs are found then -/// a clean build is required and `Err(FindLibError::Duplicate)` is returned. -fn find_lib( - deps_target_dir: &Path, - base: impl AsRef, - dep_kind: DepKind, - target: &str, -) -> Result { - let base = base.as_ref(); - let (expected_prefix, expected_extension) = dep_kind.prefix_and_extension(); - let expected_name = format!("{}{}", expected_prefix, base.display()); - - let dir = deps_target_dir.join(dep_kind.target_dir_suffix(target)); - - std::fs::read_dir(dir) - .unwrap() - .map(|entry| entry.unwrap().path()) - .filter(move |path| { - let name = { - let name = path.file_stem(); - if name.is_none() { - return false; - } - name.unwrap() - }; - - let name_matches = name.to_str().unwrap().starts_with(&expected_name) +impl Runner { + /// Attempt find the rlib that matches `base`, if multiple rlibs are found then + /// a clean build is required and `Err(FindLibError::Duplicate)` is returned. + fn find_lib( + &self, + base: impl AsRef, + dep_kind: DepKind, + target: &SpirvTarget, + ) -> Result { + let base = base.as_ref(); + let (expected_prefix, expected_extension) = dep_kind.prefix_and_extension(); + let expected_name = format!("{}{}", expected_prefix, base.display()); + + let dir = self + .deps_target_dir + .join(dep_kind.target_dir_suffix(target)); + + std::fs::read_dir(dir) + .unwrap() + .map(|entry| entry.unwrap().path()) + .filter(move |path| { + let name = { + let name = path.file_stem(); + if name.is_none() { + return false; + } + name.unwrap() + }; + + let name_matches = name.to_str().unwrap().starts_with(&expected_name) && name.len() == expected_name.len() + 17 // we expect our name, '-', and then 16 hexadecimal digits && ends_with_dash_hash(name.to_str().unwrap()); - let extension_matches = path - .extension() - .is_some_and(|ext| ext == expected_extension); - - name_matches && extension_matches - }) - .exactly_one() - .map_err(|mut iter| { - if iter.next().is_none() { - FindLibError::Missing - } else { - FindLibError::Duplicate - } - }) + let extension_matches = path + .extension() + .is_some_and(|ext| ext == expected_extension); + + name_matches && extension_matches + }) + .exactly_one() + .map_err(|mut iter| { + if iter.next().is_none() { + FindLibError::Missing + } else { + FindLibError::Duplicate + } + }) + } } /// Returns whether this string ends with a dash ('-'), followed by 16 lowercase hexadecimal characters @@ -414,10 +409,14 @@ fn dylib_path_envvar() -> &'static str { } fn dylib_path() -> Vec { - match env::var_os(dylib_path_envvar()) { + let mut dylibs = match env::var_os(dylib_path_envvar()) { Some(var) => env::split_paths(&var).collect(), None => Vec::new(), + }; + if let Ok(dir) = env::current_dir() { + dylibs.push(dir); } + dylibs } fn find_rustc_codegen_spirv() -> PathBuf { @@ -426,7 +425,8 @@ fn find_rustc_codegen_spirv() -> PathBuf { env::consts::DLL_PREFIX, env::consts::DLL_SUFFIX ); - for mut path in dylib_path() { + let dylib_paths = dylib_path(); + for mut path in dylib_paths { path.push(&filename); if path.is_file() { return path; diff --git a/tests/difftests/lib/src/scaffold/shader/rust_gpu_shader.rs b/tests/difftests/lib/src/scaffold/shader/rust_gpu_shader.rs index 59d853e731..e92f02a847 100644 --- a/tests/difftests/lib/src/scaffold/shader/rust_gpu_shader.rs +++ b/tests/difftests/lib/src/scaffold/shader/rust_gpu_shader.rs @@ -38,7 +38,6 @@ impl RustComputeShader { impl SpirvShader for RustComputeShader { fn spirv_bytes(&self) -> anyhow::Result<(Vec, String)> { let mut builder = SpirvBuilder::new(&self.path, &self.target) - .print_metadata(spirv_builder::MetadataPrintout::None) .release(true) .multimodule(false) .shader_panic_strategy(spirv_builder::ShaderPanicStrategy::SilentExit) diff --git a/tests/difftests/tests/Cargo.lock b/tests/difftests/tests/Cargo.lock index b77f1e1a79..03413d5971 100644 --- a/tests/difftests/tests/Cargo.lock +++ b/tests/difftests/tests/Cargo.lock @@ -1241,9 +1241,11 @@ name = "rustc_codegen_spirv-types" version = "0.9.0" dependencies = [ "rspirv", + "semver", "serde", "serde_json", "spirv", + "thiserror", ] [[package]]