2
2
#![ allow( clippy:: unwrap_used, reason = "this is basically a test" ) ]
3
3
//! `cargo gpu build`, analogous to `cargo build`
4
4
5
- use anyhow:: Context as _;
6
- use std:: io:: Write as _;
7
-
8
5
use crate :: args:: BuildArgs ;
9
- use crate :: linkage:: { Linkage , ShaderModule } ;
6
+ use crate :: linkage:: Linkage ;
10
7
use crate :: { install:: Install , target_spec_dir} ;
8
+ use anyhow:: Context as _;
9
+ use spirv_builder:: ModuleResult ;
10
+ use std:: io:: Write as _;
11
11
12
12
/// `cargo build` subcommands
13
13
#[ derive( clap:: Parser , Debug , serde:: Deserialize , serde:: Serialize ) ]
@@ -25,7 +25,16 @@ impl Build {
25
25
/// Entrypoint
26
26
#[ expect( clippy:: too_many_lines, reason = "It's not too confusing" ) ]
27
27
pub fn run ( & mut self ) -> anyhow:: Result < ( ) > {
28
- self . install . run ( ) ?;
28
+ let ( rustc_codegen_spirv_location, toolchain_channel) = self . install . run ( ) ?;
29
+
30
+ let builder = & mut self . build_args . spirv_builder ;
31
+ builder. rustc_codegen_spirv_location = Some ( rustc_codegen_spirv_location) ;
32
+ builder. toolchain_overwrite = Some ( toolchain_channel) ;
33
+ builder. path_to_crate = Some ( self . install . spirv_install . shader_crate . clone ( ) ) ;
34
+ builder. path_to_target_spec = Some ( target_spec_dir ( ) ?. join ( format ! (
35
+ "{}.json" ,
36
+ builder. target. as_ref( ) . context( "expect target to be set" ) ?
37
+ ) ) ) ;
29
38
30
39
// Ensure the shader output dir exists
31
40
log:: debug!(
@@ -47,96 +56,58 @@ impl Build {
47
56
std:: env:: current_dir( ) ?. display( )
48
57
) ;
49
58
50
- if !self . build_args . watch {
51
- self . build_args . spirv_builder . target = Some (
52
- target_spec_dir ( ) ?
53
- . join ( format ! (
54
- "{}.json" ,
55
- self . build_args
56
- . spirv_builder
57
- . target
58
- . as_ref( )
59
- . context( "expect target to be set" ) ?
60
- ) )
61
- . display ( )
62
- . to_string ( ) ,
63
- ) ;
64
- }
65
-
66
- let args_as_json = serde_json:: json!( {
67
- "install" : self . install. spirv_install,
68
- "build" : self . build_args
69
- } ) ;
70
- let arg = serde_json:: to_string_pretty ( & args_as_json) ?;
71
- log:: info!( "using spirv-builder-cli arg: {arg}" ) ;
72
-
73
59
if !self . build_args . watch {
74
60
crate :: user_output!(
75
- "Running `spirv-builder-cli` to compile shader at {}...\n " ,
61
+ "Compiling shaders at {}...\n " ,
76
62
self . install. spirv_install. shader_crate. display( )
77
63
) ;
78
64
}
79
65
80
- // TODO Call spirv-builder-cli to compile the shaders.
81
- let output = std:: process:: Command :: new ( "TODO_DUMMY_PLEASE_CHANGE_ME" )
82
- . arg ( arg)
83
- . stdout ( std:: process:: Stdio :: inherit ( ) )
84
- . stderr ( std:: process:: Stdio :: inherit ( ) )
85
- . output ( ) ?;
86
- anyhow:: ensure!( output. status. success( ) , "build failed" ) ;
87
-
88
- let spirv_manifest = self . build_args . output_dir . join ( "spirv-manifest.json" ) ;
89
- if spirv_manifest. is_file ( ) {
90
- log:: debug!(
91
- "successfully built shaders, raw manifest is at '{}'" ,
92
- spirv_manifest. display( )
93
- ) ;
94
- } else {
95
- log:: error!( "missing raw manifest '{}'" , spirv_manifest. display( ) ) ;
96
- anyhow:: bail!( "missing raw manifest" ) ;
97
- }
98
-
99
- let shaders: Vec < ShaderModule > =
100
- serde_json:: from_reader ( std:: fs:: File :: open ( & spirv_manifest) ?) ?;
101
-
66
+ let result = self . build_args . spirv_builder . build ( ) ?;
67
+
68
+ let shaders = match & result. module {
69
+ ModuleResult :: MultiModule ( modules) => {
70
+ assert ! ( !modules. is_empty( ) , "No shader modules to compile" ) ;
71
+ modules. iter ( ) . collect :: < Vec < _ > > ( )
72
+ }
73
+ ModuleResult :: SingleModule ( filepath) => result
74
+ . entry_points
75
+ . iter ( )
76
+ . map ( |entry| ( entry, filepath) )
77
+ . collect :: < Vec < _ > > ( ) ,
78
+ } ;
102
79
let mut linkage: Vec < Linkage > = shaders
103
80
. into_iter ( )
104
- . map (
105
- |ShaderModule {
106
- entry,
107
- path : filepath,
108
- } |
109
- -> anyhow:: Result < Linkage > {
110
- use relative_path:: PathExt as _;
111
- let path = self . build_args . output_dir . join (
112
- filepath
113
- . file_name ( )
114
- . context ( "Couldn't parse file name from shader module path" ) ?,
115
- ) ;
116
- log:: debug!( "copying {} to {}" , filepath. display( ) , path. display( ) ) ;
117
- std:: fs:: copy ( & filepath, & path) ?;
118
- log:: debug!(
119
- "linkage of {} relative to {}" ,
120
- path. display( ) ,
121
- self . install. spirv_install. shader_crate. display( )
122
- ) ;
123
- let spv_path = path
124
- . relative_to ( & self . install . spirv_install . shader_crate )
125
- . map_or ( path, |path_relative_to_shader_crate| {
126
- path_relative_to_shader_crate. to_path ( "" )
127
- } ) ;
128
- Ok ( Linkage :: new ( entry, spv_path) )
129
- } ,
130
- )
81
+ . map ( |( entry, filepath) | -> anyhow:: Result < Linkage > {
82
+ use relative_path:: PathExt as _;
83
+ let path = self . build_args . output_dir . join (
84
+ filepath
85
+ . file_name ( )
86
+ . context ( "Couldn't parse file name from shader module path" ) ?,
87
+ ) ;
88
+ log:: debug!( "copying {} to {}" , filepath. display( ) , path. display( ) ) ;
89
+ std:: fs:: copy ( & filepath, & path) ?;
90
+ log:: debug!(
91
+ "linkage of {} relative to {}" ,
92
+ path. display( ) ,
93
+ self . install. spirv_install. shader_crate. display( )
94
+ ) ;
95
+ let spv_path = path
96
+ . relative_to ( & self . install . spirv_install . shader_crate )
97
+ . map_or ( path, |path_relative_to_shader_crate| {
98
+ path_relative_to_shader_crate. to_path ( "" )
99
+ } ) ;
100
+ Ok ( Linkage :: new ( entry, spv_path) )
101
+ } )
131
102
. collect :: < anyhow:: Result < Vec < Linkage > > > ( ) ?;
103
+ // Sort the contents so the output is deterministic
104
+ linkage. sort ( ) ;
132
105
133
106
// Write the shader manifest json file
134
107
let manifest_path = self
135
108
. build_args
136
109
. output_dir
137
110
. join ( & self . build_args . manifest_file ) ;
138
- // Sort the contents so the output is deterministic
139
- linkage. sort ( ) ;
140
111
let json = serde_json:: to_string_pretty ( & linkage) ?;
141
112
let mut file = std:: fs:: File :: create ( & manifest_path) . with_context ( || {
142
113
format ! (
@@ -152,14 +123,6 @@ impl Build {
152
123
} ) ?;
153
124
154
125
log:: info!( "wrote manifest to '{}'" , manifest_path. display( ) ) ;
155
-
156
- if spirv_manifest. is_file ( ) {
157
- log:: debug!(
158
- "removing spirv-manifest.json file '{}'" ,
159
- spirv_manifest. display( )
160
- ) ;
161
- std:: fs:: remove_file ( spirv_manifest) ?;
162
- }
163
126
Ok ( ( ) )
164
127
}
165
128
}
0 commit comments