1
1
//! Install a dedicated per-shader crate that has the `rust-gpu` compiler in it.
2
2
use std:: io:: Write as _;
3
3
4
+ use anyhow:: Context as _;
5
+
4
6
use crate :: { cache_dir, spirv_cli:: SpirvCli , spirv_source:: SpirvSource , target_spec_dir} ;
5
7
6
8
/// These are the files needed to create the dedicated, per-shader `rust-gpu` builder create.
@@ -120,7 +122,7 @@ pub struct Install {
120
122
121
123
impl Install {
122
124
/// Returns a [`SpirvCLI`] instance, responsible for ensuring the right version of the `spirv-builder-cli` crate.
123
- fn spirv_cli ( & self , shader_crate_path : & std:: path:: PathBuf ) -> SpirvCli {
125
+ fn spirv_cli ( & self , shader_crate_path : & std:: path:: PathBuf ) -> anyhow :: Result < SpirvCli > {
124
126
SpirvCli :: new (
125
127
shader_crate_path,
126
128
self . spirv_builder_source . clone ( ) ,
@@ -130,20 +132,21 @@ impl Install {
130
132
}
131
133
132
134
/// Create the `spirv-builder-cli` crate.
133
- fn write_source_files ( & self ) {
134
- let spirv_cli = self . spirv_cli ( & self . shader_crate ) ;
135
- let checkout = spirv_cli. cached_checkout_path ( ) ;
136
- std:: fs:: create_dir_all ( checkout. join ( "src" ) ) . unwrap ( ) ;
135
+ fn write_source_files ( & self ) -> anyhow :: Result < ( ) > {
136
+ let spirv_cli = self . spirv_cli ( & self . shader_crate ) ? ;
137
+ let checkout = spirv_cli. cached_checkout_path ( ) ? ;
138
+ std:: fs:: create_dir_all ( checkout. join ( "src" ) ) ? ;
137
139
for ( filename, contents) in SPIRV_BUILDER_FILES {
138
140
log:: debug!( "writing {filename}" ) ;
139
141
let path = checkout. join ( filename) ;
140
- let mut file = std:: fs:: File :: create ( & path) . unwrap ( ) ;
142
+ let mut file = std:: fs:: File :: create ( & path) ? ;
141
143
let mut replaced_contents = contents. replace ( "${CHANNEL}" , & spirv_cli. channel ) ;
142
144
if filename == & "Cargo.toml" {
143
145
replaced_contents = Self :: update_cargo_toml ( & replaced_contents, & spirv_cli. source ) ;
144
146
}
145
- file. write_all ( replaced_contents. as_bytes ( ) ) . unwrap ( ) ;
147
+ file. write_all ( replaced_contents. as_bytes ( ) ) ? ;
146
148
}
149
+ Ok ( ( ) )
147
150
}
148
151
149
152
/// Update the `Cargo.toml` file in the `spirv-builder-cli` crate so that it contains
@@ -176,33 +179,30 @@ impl Install {
176
179
}
177
180
178
181
/// Add the target spec files to the crate.
179
- fn write_target_spec_files ( & self ) {
182
+ fn write_target_spec_files ( & self ) -> anyhow :: Result < ( ) > {
180
183
for ( filename, contents) in TARGET_SPECS {
181
- let path = target_spec_dir ( ) . join ( filename) ;
184
+ let path = target_spec_dir ( ) ? . join ( filename) ;
182
185
if !path. is_file ( ) || self . force_spirv_cli_rebuild {
183
- let mut file = std:: fs:: File :: create ( & path) . unwrap ( ) ;
184
- file. write_all ( contents. as_bytes ( ) ) . unwrap ( ) ;
186
+ let mut file = std:: fs:: File :: create ( & path) ? ;
187
+ file. write_all ( contents. as_bytes ( ) ) ? ;
185
188
}
186
189
}
190
+ Ok ( ( ) )
187
191
}
188
192
189
193
/// Install the binary pair and return the paths, (dylib, cli).
190
- pub fn run ( & self ) -> ( std:: path:: PathBuf , std:: path:: PathBuf ) {
194
+ pub fn run ( & self ) -> anyhow :: Result < ( std:: path:: PathBuf , std:: path:: PathBuf ) > {
191
195
// Ensure the cache dir exists
192
- let cache_dir = cache_dir ( ) ;
196
+ let cache_dir = cache_dir ( ) ? ;
193
197
log:: info!( "cache directory is '{}'" , cache_dir. display( ) ) ;
194
- std:: fs:: create_dir_all ( & cache_dir) . unwrap_or_else ( |error| {
195
- log:: error!(
196
- "could not create cache directory '{}': {error}" ,
197
- cache_dir. display( )
198
- ) ;
199
- panic ! ( "could not create cache dir" ) ;
200
- } ) ;
198
+ std:: fs:: create_dir_all ( & cache_dir) . with_context ( || {
199
+ format ! ( "could not create cache directory '{}'" , cache_dir. display( ) )
200
+ } ) ?;
201
201
202
- let spirv_version = self . spirv_cli ( & self . shader_crate ) ;
203
- spirv_version. ensure_toolchain_and_components_exist ( ) ;
202
+ let spirv_version = self . spirv_cli ( & self . shader_crate ) ? ;
203
+ spirv_version. ensure_toolchain_and_components_exist ( ) ? ;
204
204
205
- let checkout = spirv_version. cached_checkout_path ( ) ;
205
+ let checkout = spirv_version. cached_checkout_path ( ) ? ;
206
206
let release = checkout. join ( "target" ) . join ( "release" ) ;
207
207
208
208
let dylib_filename = format ! (
@@ -227,8 +227,8 @@ impl Install {
227
227
"writing spirv-builder-cli source files into '{}'" ,
228
228
checkout. display( )
229
229
) ;
230
- self . write_source_files ( ) ;
231
- self . write_target_spec_files ( ) ;
230
+ self . write_source_files ( ) ? ;
231
+ self . write_target_spec_files ( ) ? ;
232
232
233
233
let mut command = std:: process:: Command :: new ( "cargo" ) ;
234
234
command
@@ -239,24 +239,23 @@ impl Install {
239
239
240
240
command. args ( [
241
241
"--features" ,
242
- & Self :: get_required_spirv_builder_version ( spirv_version. date ) ,
242
+ & Self :: get_required_spirv_builder_version ( spirv_version. date ) ? ,
243
243
] ) ;
244
244
245
245
log:: debug!( "building artifacts with `{:?}`" , command) ;
246
246
247
247
let output = command
248
248
. stdout ( std:: process:: Stdio :: inherit ( ) )
249
249
. stderr ( std:: process:: Stdio :: inherit ( ) )
250
- . output ( )
251
- . unwrap ( ) ;
252
- assert ! ( output. status. success( ) , "...build error!" ) ;
250
+ . output ( ) ?;
251
+ anyhow:: ensure!( output. status. success( ) , "...build error!" ) ;
253
252
254
253
if dylib_path. is_file ( ) {
255
254
log:: info!( "successfully built {}" , dylib_path. display( ) ) ;
256
- std:: fs:: rename ( & dylib_path, & dest_dylib_path) . unwrap ( ) ;
255
+ std:: fs:: rename ( & dylib_path, & dest_dylib_path) ? ;
257
256
} else {
258
257
log:: error!( "could not find {}" , dylib_path. display( ) ) ;
259
- panic ! ( "spirv-builder-cli build failed" ) ;
258
+ anyhow :: bail !( "spirv-builder-cli build failed" ) ;
260
259
}
261
260
262
261
let cli_path = if cfg ! ( target_os = "windows" ) {
@@ -266,18 +265,18 @@ impl Install {
266
265
} ;
267
266
if cli_path. is_file ( ) {
268
267
log:: info!( "successfully built {}" , cli_path. display( ) ) ;
269
- std:: fs:: rename ( & cli_path, & dest_cli_path) . unwrap ( ) ;
268
+ std:: fs:: rename ( & cli_path, & dest_cli_path) ? ;
270
269
} else {
271
270
log:: error!( "could not find {}" , cli_path. display( ) ) ;
272
271
log:: debug!( "contents of '{}':" , release. display( ) ) ;
273
- for maybe_entry in std:: fs:: read_dir ( & release) . unwrap ( ) {
274
- let entry = maybe_entry. unwrap ( ) ;
272
+ for maybe_entry in std:: fs:: read_dir ( & release) ? {
273
+ let entry = maybe_entry? ;
275
274
log:: debug!( "{}" , entry. file_name( ) . to_string_lossy( ) ) ;
276
275
}
277
- panic ! ( "spirv-builder-cli build failed" ) ;
276
+ anyhow :: bail !( "spirv-builder-cli build failed" ) ;
278
277
}
279
278
}
280
- ( dest_dylib_path, dest_cli_path)
279
+ Ok ( ( dest_dylib_path, dest_cli_path) )
281
280
}
282
281
283
282
/// The `spirv-builder` crate from the main `rust-gpu` repo hasn't always been setup to
@@ -287,15 +286,15 @@ impl Install {
287
286
/// TODO:
288
287
/// * Warn the user that certain `cargo-gpu` features aren't available when building with
289
288
/// older versions of `spirv-builder`, eg setting the target spec.
290
- fn get_required_spirv_builder_version ( date : chrono:: NaiveDate ) -> String {
289
+ fn get_required_spirv_builder_version ( date : chrono:: NaiveDate ) -> anyhow :: Result < String > {
291
290
let parse_date = chrono:: NaiveDate :: parse_from_str;
292
- let pre_cli_date = parse_date ( "2024-04-24" , "%Y-%m-%d" ) . unwrap ( ) ;
291
+ let pre_cli_date = parse_date ( "2024-04-24" , "%Y-%m-%d" ) ? ;
293
292
294
- if date < pre_cli_date {
293
+ Ok ( if date < pre_cli_date {
295
294
"spirv-builder-pre-cli"
296
295
} else {
297
296
"spirv-builder-0_10"
298
297
}
299
- . into ( )
298
+ . into ( ) )
300
299
}
301
300
}
0 commit comments