@@ -11,12 +11,67 @@ use log::{info, trace};
1111use spirv_builder:: SpirvBuilder ;
1212use std:: path:: { Path , PathBuf } ;
1313
14+ /// Represents a functional backend installation, whether it was cached or just installed.
15+ #[ derive( Clone , Debug ) ]
16+ #[ expect(
17+ clippy:: exhaustive_structs,
18+ reason = "never adding private members to this struct"
19+ ) ]
20+ pub struct InstalledBackend {
21+ /// path to the `rustc_codegen_spirv` dylib
22+ pub rustc_codegen_spirv_location : PathBuf ,
23+ /// toolchain channel name
24+ pub toolchain_channel : String ,
25+ /// directory with target-specs json files
26+ pub target_spec_dir : PathBuf ,
27+ }
28+
29+ impl InstalledBackend {
30+ /// Creates a new `SpirvBuilder` configured to use this installed backend.
31+ #[ expect(
32+ clippy:: missing_panics_doc,
33+ clippy:: expect_used,
34+ reason = "unreachable"
35+ ) ]
36+ #[ expect( clippy:: impl_trait_in_params, reason = "forwarding spirv-builder API" ) ]
37+ #[ inline]
38+ pub fn to_spirv_builder (
39+ & self ,
40+ path_to_crate : impl AsRef < Path > ,
41+ target : impl Into < String > ,
42+ ) -> SpirvBuilder {
43+ let mut builder = SpirvBuilder :: new ( path_to_crate, target) ;
44+ self . configure_spirv_builder ( & mut builder)
45+ . expect ( "unreachable" ) ;
46+ builder
47+ }
48+
49+ /// Configures the supplied [`SpirvBuilder`]. `SpirvBuilder.target` must be set and must not change after calling this function.
50+ ///
51+ /// # Errors
52+ /// if `SpirvBuilder.target` is not set
53+ #[ inline]
54+ pub fn configure_spirv_builder ( & self , builder : & mut SpirvBuilder ) -> anyhow:: Result < ( ) > {
55+ builder. rustc_codegen_spirv_location = Some ( self . rustc_codegen_spirv_location . clone ( ) ) ;
56+ builder. toolchain_overwrite = Some ( self . toolchain_channel . clone ( ) ) ;
57+ builder. path_to_target_spec = Some ( self . target_spec_dir . join ( format ! (
58+ "{}.json" ,
59+ builder. target. as_ref( ) . context( "expect target to be set" ) ?
60+ ) ) ) ;
61+ Ok ( ( ) )
62+ }
63+ }
64+
1465/// Args for an install
1566#[ expect(
1667 clippy:: struct_excessive_bools,
1768 reason = "cmdline args have many bools"
1869) ]
1970#[ derive( clap:: Parser , Debug , Clone , serde:: Deserialize , serde:: Serialize ) ]
71+ #[ expect(
72+ clippy:: exhaustive_structs,
73+ reason = "never adding private members to this struct"
74+ ) ]
2075pub struct Install {
2176 /// Directory containing the shader crate to compile.
2277 #[ clap( long, default_value = "./" ) ]
@@ -81,7 +136,9 @@ pub struct Install {
81136
82137impl Install {
83138 /// Create a default install for a shader crate of some path
84- pub fn from_shader_crate ( shader_crate : PathBuf ) -> Self {
139+ #[ inline]
140+ #[ must_use]
141+ pub const fn from_shader_crate ( shader_crate : PathBuf ) -> Self {
85142 Self {
86143 shader_crate,
87144 spirv_builder_source : None ,
@@ -92,45 +149,7 @@ impl Install {
92149 force_overwrite_lockfiles_v4_to_v3 : false ,
93150 }
94151 }
95- }
96152
97- /// Represents a functional backend installation, whether it was cached or just installed.
98- #[ derive( Clone , Debug ) ]
99- pub struct InstalledBackend {
100- /// path to the `rustc_codegen_spirv` dylib
101- pub rustc_codegen_spirv_location : PathBuf ,
102- /// toolchain channel name
103- pub toolchain_channel : String ,
104- /// directory with target-specs json files
105- pub target_spec_dir : PathBuf ,
106- }
107-
108- impl InstalledBackend {
109- /// Creates a new `SpirvBuilder` configured to use this installed backend.
110- pub fn to_spirv_builder (
111- & self ,
112- path_to_crate : impl AsRef < Path > ,
113- target : impl Into < String > ,
114- ) -> SpirvBuilder {
115- let mut builder = SpirvBuilder :: new ( path_to_crate, target) ;
116- self . configure_spirv_builder ( & mut builder)
117- . expect ( "unreachable" ) ;
118- builder
119- }
120-
121- /// Configures the supplied [`SpirvBuilder`]. `SpirvBuilder.target` must be set and must not change after calling this function.
122- pub fn configure_spirv_builder ( & self , builder : & mut SpirvBuilder ) -> anyhow:: Result < ( ) > {
123- builder. rustc_codegen_spirv_location = Some ( self . rustc_codegen_spirv_location . clone ( ) ) ;
124- builder. toolchain_overwrite = Some ( self . toolchain_channel . clone ( ) ) ;
125- builder. path_to_target_spec = Some ( self . target_spec_dir . join ( format ! (
126- "{}.json" ,
127- builder. target. as_ref( ) . context( "expect target to be set" ) ?
128- ) ) ) ;
129- Ok ( ( ) )
130- }
131- }
132-
133- impl Install {
134153 /// Create the `rustc_codegen_spirv_dummy` crate that depends on `rustc_codegen_spirv`
135154 fn write_source_files ( source : & SpirvSource , checkout : & Path ) -> anyhow:: Result < ( ) > {
136155 // skip writing a dummy project if we use a local rust-gpu checkout
@@ -252,7 +271,11 @@ package = "rustc_codegen_spirv"
252271 Ok ( target_specs_dst)
253272 }
254273
255- /// Install the binary pair and return the `(dylib_path, toolchain_channel)`.
274+ /// Install the binary pair and return the [`InstalledBackend`], from which you can create [`SpirvBuilder`] instances.
275+ ///
276+ /// # Errors
277+ /// If the installation somehow fails.
278+ #[ inline]
256279 #[ expect( clippy:: too_many_lines, reason = "it's fine" ) ]
257280 pub fn run ( & self ) -> anyhow:: Result < InstalledBackend > {
258281 // Ensure the cache dir exists
0 commit comments