22#![ allow( clippy:: unwrap_used, reason = "this is basically a test" ) ]
33//! `cargo gpu build`, analogous to `cargo build`
44
5- use crate :: args:: BuildArgs ;
65use crate :: linkage:: Linkage ;
76use crate :: lockfile:: LockfileMismatchHandler ;
87use crate :: { install:: Install , target_spec_dir} ;
98use anyhow:: Context as _;
10- use spirv_builder:: { CompileResult , ModuleResult } ;
9+ use spirv_builder:: { CompileResult , ModuleResult , SpirvBuilder } ;
1110use std:: io:: Write as _;
11+ use std:: path:: PathBuf ;
12+
13+ /// Args for just a build
14+ #[ derive( clap:: Parser , Debug , Clone , serde:: Deserialize , serde:: Serialize ) ]
15+ #[ non_exhaustive]
16+ pub struct BuildArgs {
17+ /// Path to the output directory for the compiled shaders.
18+ #[ clap( long, short, default_value = "./" ) ]
19+ pub output_dir : PathBuf ,
20+
21+ /// Watch the shader crate directory and automatically recompile on changes.
22+ #[ clap( long, short, action) ]
23+ pub watch : bool ,
24+
25+ /// the flattened [`SpirvBuilder`]
26+ #[ clap( flatten) ]
27+ #[ serde( flatten) ]
28+ pub spirv_builder : SpirvBuilder ,
29+
30+ ///Renames the manifest.json file to the given name
31+ #[ clap( long, short, default_value = "manifest.json" ) ]
32+ pub manifest_file : String ,
33+ }
34+
35+ impl Default for BuildArgs {
36+ #[ inline]
37+ fn default ( ) -> Self {
38+ Self {
39+ output_dir : PathBuf :: from ( "./" ) ,
40+ watch : false ,
41+ spirv_builder : SpirvBuilder :: default ( ) ,
42+ manifest_file : String :: from ( "manifest.json" ) ,
43+ }
44+ }
45+ }
1246
1347/// `cargo build` subcommands
1448#[ derive( Clone , clap:: Parser , Debug , serde:: Deserialize , serde:: Serialize ) ]
@@ -19,7 +53,7 @@ pub struct Build {
1953
2054 /// CLI args for configuring the build of the shader
2155 #[ clap( flatten) ]
22- pub build_args : BuildArgs ,
56+ pub build : BuildArgs ,
2357}
2458
2559impl Build {
@@ -28,17 +62,15 @@ impl Build {
2862 let ( rustc_codegen_spirv_location, toolchain_channel) = self . install . run ( ) ?;
2963
3064 let _lockfile_mismatch_handler = LockfileMismatchHandler :: new (
31- & self . install . spirv_install . shader_crate ,
65+ & self . install . shader_crate ,
3266 & toolchain_channel,
33- self . install
34- . spirv_install
35- . force_overwrite_lockfiles_v4_to_v3 ,
67+ self . install . force_overwrite_lockfiles_v4_to_v3 ,
3668 ) ?;
3769
38- let builder = & mut self . build_args . spirv_builder ;
70+ let builder = & mut self . build . spirv_builder ;
3971 builder. rustc_codegen_spirv_location = Some ( rustc_codegen_spirv_location) ;
4072 builder. toolchain_overwrite = Some ( toolchain_channel) ;
41- builder. path_to_crate = Some ( self . install . spirv_install . shader_crate . clone ( ) ) ;
73+ builder. path_to_crate = Some ( self . install . shader_crate . clone ( ) ) ;
4274 builder. path_to_target_spec = Some ( target_spec_dir ( ) ?. join ( format ! (
4375 "{}.json" ,
4476 builder. target. as_ref( ) . context( "expect target to be set" ) ?
@@ -47,26 +79,25 @@ impl Build {
4779 // Ensure the shader output dir exists
4880 log:: debug!(
4981 "ensuring output-dir '{}' exists" ,
50- self . build_args . output_dir. display( )
82+ self . build . output_dir. display( )
5183 ) ;
52- std:: fs:: create_dir_all ( & self . build_args . output_dir ) ?;
53- let canonicalized = self . build_args . output_dir . canonicalize ( ) ?;
84+ std:: fs:: create_dir_all ( & self . build . output_dir ) ?;
85+ let canonicalized = self . build . output_dir . canonicalize ( ) ?;
5486 log:: debug!( "canonicalized output dir: {canonicalized:?}" ) ;
55- self . build_args . output_dir = canonicalized;
87+ self . build . output_dir = canonicalized;
5688
5789 // Ensure the shader crate exists
58- self . install . spirv_install . shader_crate =
59- self . install . spirv_install . shader_crate . canonicalize ( ) ?;
90+ self . install . shader_crate = self . install . shader_crate . canonicalize ( ) ?;
6091 anyhow:: ensure!(
61- self . install. spirv_install . shader_crate. exists( ) ,
92+ self . install. shader_crate. exists( ) ,
6293 "shader crate '{}' does not exist. (Current dir is '{}')" ,
63- self . install. spirv_install . shader_crate. display( ) ,
94+ self . install. shader_crate. display( ) ,
6495 std:: env:: current_dir( ) ?. display( )
6596 ) ;
6697
67- if self . build_args . watch {
98+ if self . build . watch {
6899 let this = self . clone ( ) ;
69- self . build_args
100+ self . build
70101 . spirv_builder
71102 . watch ( move |result, accept| {
72103 let result1 = this. parse_compilation_result ( & result) ;
@@ -79,9 +110,9 @@ impl Build {
79110 } else {
80111 crate :: user_output!(
81112 "Compiling shaders at {}...\n " ,
82- self . install. spirv_install . shader_crate. display( )
113+ self . install. shader_crate. display( )
83114 ) ;
84- let result = self . build_args . spirv_builder . build ( ) ?;
115+ let result = self . build . spirv_builder . build ( ) ?;
85116 self . parse_compilation_result ( & result) ?;
86117 }
87118 Ok ( ( ) )
@@ -104,7 +135,7 @@ impl Build {
104135 . into_iter ( )
105136 . map ( |( entry, filepath) | -> anyhow:: Result < Linkage > {
106137 use relative_path:: PathExt as _;
107- let path = self . build_args . output_dir . join (
138+ let path = self . build . output_dir . join (
108139 filepath
109140 . file_name ( )
110141 . context ( "Couldn't parse file name from shader module path" ) ?,
@@ -114,10 +145,10 @@ impl Build {
114145 log:: debug!(
115146 "linkage of {} relative to {}" ,
116147 path. display( ) ,
117- self . install. spirv_install . shader_crate. display( )
148+ self . install. shader_crate. display( )
118149 ) ;
119150 let spv_path = path
120- . relative_to ( & self . install . spirv_install . shader_crate )
151+ . relative_to ( & self . install . shader_crate )
121152 . map_or ( path, |path_relative_to_shader_crate| {
122153 path_relative_to_shader_crate. to_path ( "" )
123154 } ) ;
@@ -128,10 +159,7 @@ impl Build {
128159 linkage. sort ( ) ;
129160
130161 // Write the shader manifest json file
131- let manifest_path = self
132- . build_args
133- . output_dir
134- . join ( & self . build_args . manifest_file ) ;
162+ let manifest_path = self . build . output_dir . join ( & self . build . manifest_file ) ;
135163 let json = serde_json:: to_string_pretty ( & linkage) ?;
136164 let mut file = std:: fs:: File :: create ( & manifest_path) . with_context ( || {
137165 format ! (
@@ -176,8 +204,8 @@ mod test {
176204 command : Command :: Build ( build) ,
177205 } = Cli :: parse_from ( args)
178206 {
179- assert_eq ! ( shader_crate_path, build. install. spirv_install . shader_crate) ;
180- assert_eq ! ( output_dir, build. build_args . output_dir) ;
207+ assert_eq ! ( shader_crate_path, build. install. shader_crate) ;
208+ assert_eq ! ( output_dir, build. build . output_dir) ;
181209
182210 // TODO:
183211 // For some reason running a full build (`build.run()`) inside tests fails on Windows.
0 commit comments