22#![ allow( clippy:: unwrap_used, reason = "this is basically a test" ) ]
33//! `cargo gpu build`, analogous to `cargo build`
44
5- use anyhow:: Context as _;
6- use std:: io:: Write as _;
7-
85use crate :: args:: BuildArgs ;
9- use crate :: linkage:: { Linkage , ShaderModule } ;
6+ use crate :: linkage:: Linkage ;
107use crate :: { install:: Install , target_spec_dir} ;
8+ use anyhow:: Context as _;
9+ use spirv_builder:: ModuleResult ;
10+ use std:: io:: Write as _;
1111
1212/// `cargo build` subcommands
1313#[ derive( clap:: Parser , Debug , serde:: Deserialize , serde:: Serialize ) ]
@@ -25,7 +25,16 @@ impl Build {
2525 /// Entrypoint
2626 #[ expect( clippy:: too_many_lines, reason = "It's not too confusing" ) ]
2727 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+ ) ) ) ;
2938
3039 // Ensure the shader output dir exists
3140 log:: debug!(
@@ -47,96 +56,58 @@ impl Build {
4756 std:: env:: current_dir( ) ?. display( )
4857 ) ;
4958
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-
7359 if !self . build_args . watch {
7460 crate :: user_output!(
75- "Running `spirv-builder-cli` to compile shader at {}...\n " ,
61+ "Compiling shaders at {}...\n " ,
7662 self . install. spirv_install. shader_crate. display( )
7763 ) ;
7864 }
7965
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+ } ;
10279 let mut linkage: Vec < Linkage > = shaders
10380 . 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+ } )
131102 . collect :: < anyhow:: Result < Vec < Linkage > > > ( ) ?;
103+ // Sort the contents so the output is deterministic
104+ linkage. sort ( ) ;
132105
133106 // Write the shader manifest json file
134107 let manifest_path = self
135108 . build_args
136109 . output_dir
137110 . join ( & self . build_args . manifest_file ) ;
138- // Sort the contents so the output is deterministic
139- linkage. sort ( ) ;
140111 let json = serde_json:: to_string_pretty ( & linkage) ?;
141112 let mut file = std:: fs:: File :: create ( & manifest_path) . with_context ( || {
142113 format ! (
@@ -152,14 +123,6 @@ impl Build {
152123 } ) ?;
153124
154125 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- }
163126 Ok ( ( ) )
164127 }
165128}
0 commit comments