| 
1 | 1 | //! `cargo gpu build`, analogous to `cargo build`  | 
2 | 2 | 
  | 
3 | 3 | use core::convert::Infallible;  | 
4 |  | -use std::{io::Write as _, panic, path::PathBuf};  | 
 | 4 | +use std::{  | 
 | 5 | +    io::Write as _,  | 
 | 6 | +    panic,  | 
 | 7 | +    path::{Path, PathBuf},  | 
 | 8 | +    thread,  | 
 | 9 | +};  | 
5 | 10 | 
 
  | 
6 | 11 | use anyhow::Context as _;  | 
7 | 12 | use cargo_gpu_build::{  | 
8 | 13 |     build::{CargoGpuBuilder, CargoGpuBuilderParams},  | 
9 | 14 |     spirv_builder::{CompileResult, ModuleResult, SpirvBuilder},  | 
10 | 15 | };  | 
11 | 16 | 
 
  | 
12 |  | -use crate::{install::Install, linkage::Linkage, user_consent::ask_for_user_consent};  | 
 | 17 | +use crate::{  | 
 | 18 | +    install::InstallArgs,  | 
 | 19 | +    linkage::Linkage,  | 
 | 20 | +    metadata::{CargoMetadata, CargoMetadataSource},  | 
 | 21 | +    user_consent::ask_for_user_consent,  | 
 | 22 | +};  | 
13 | 23 | 
 
  | 
14 | 24 | /// Args for just a build.  | 
15 | 25 | #[derive(Debug, Clone, clap::Parser, serde::Deserialize, serde::Serialize)]  | 
@@ -47,12 +57,12 @@ impl Default for BuildArgs {  | 
47 | 57 | }  | 
48 | 58 | 
 
  | 
49 | 59 | /// `cargo build` subcommands.  | 
50 |  | -#[derive(Clone, Debug, clap::Parser, serde::Deserialize, serde::Serialize)]  | 
 | 60 | +#[derive(Clone, Debug, Default, clap::Parser, serde::Deserialize, serde::Serialize)]  | 
51 | 61 | #[non_exhaustive]  | 
52 | 62 | pub struct Build {  | 
53 | 63 |     /// CLI args for install the `rust-gpu` compiler and components.  | 
54 | 64 |     #[clap(flatten)]  | 
55 |  | -    pub install: Install,  | 
 | 65 | +    pub install: InstallArgs,  | 
56 | 66 | 
 
  | 
57 | 67 |     /// CLI args for configuring the build of the shader.  | 
58 | 68 |     #[clap(flatten)]  | 
@@ -107,7 +117,7 @@ impl Build {  | 
107 | 117 |     fn watch(&self, mut crate_builder: CargoGpuBuilder) -> anyhow::Result<Infallible> {  | 
108 | 118 |         let this = self.clone();  | 
109 | 119 |         let mut watcher = crate_builder.watch()?;  | 
110 |  | -        let watch_thread = std::thread::spawn(move || -> ! {  | 
 | 120 | +        let watch_thread = thread::spawn(move || -> ! {  | 
111 | 121 |             loop {  | 
112 | 122 |                 let compile_result = match watcher.recv() {  | 
113 | 123 |                     Ok(compile_result) => compile_result,  | 
@@ -191,26 +201,51 @@ impl Build {  | 
191 | 201 |     }  | 
192 | 202 | }  | 
193 | 203 | 
 
  | 
 | 204 | +impl CargoMetadata for Build {  | 
 | 205 | +    fn patch(&mut self, shader_crate: &Path, source: CargoMetadataSource<'_>) {  | 
 | 206 | +        let CargoMetadataSource::Crate(_) = source else {  | 
 | 207 | +            return;  | 
 | 208 | +        };  | 
 | 209 | + | 
 | 210 | +        let output_dir = self.build.output_dir.as_path();  | 
 | 211 | +        log::debug!(  | 
 | 212 | +            "found output dir path in crate metadata: {}",  | 
 | 213 | +            output_dir.display()  | 
 | 214 | +        );  | 
 | 215 | + | 
 | 216 | +        let new_output_dir = shader_crate.join(output_dir);  | 
 | 217 | +        log::debug!(  | 
 | 218 | +            "setting that to be relative to the Cargo.toml it was found in: {}",  | 
 | 219 | +            new_output_dir.display()  | 
 | 220 | +        );  | 
 | 221 | + | 
 | 222 | +        self.build.output_dir = new_output_dir;  | 
 | 223 | +    }  | 
 | 224 | +}  | 
 | 225 | + | 
194 | 226 | #[cfg(test)]  | 
195 | 227 | mod test {  | 
196 | 228 |     use clap::Parser as _;  | 
197 | 229 | 
 
  | 
198 |  | -    use crate::{Cli, Command};  | 
 | 230 | +    use crate::{  | 
 | 231 | +        test::{shader_crate_template_path, tests_teardown},  | 
 | 232 | +        Cli, Command,  | 
 | 233 | +    };  | 
199 | 234 | 
 
  | 
200 | 235 |     #[test_log::test]  | 
201 | 236 |     fn builder_from_params() {  | 
202 |  | -        crate::test::tests_teardown();  | 
 | 237 | +        tests_teardown();  | 
203 | 238 | 
 
  | 
204 |  | -        let shader_crate_path = crate::test::shader_crate_template_path();  | 
 | 239 | +        let shader_crate_path = shader_crate_template_path();  | 
205 | 240 |         let output_dir = shader_crate_path.join("shaders");  | 
206 | 241 | 
 
  | 
207 | 242 |         let args = [  | 
208 |  | -            "target/debug/cargo-gpu",  | 
209 |  | -            "build",  | 
210 |  | -            "--shader-crate",  | 
211 |  | -            &format!("{}", shader_crate_path.display()),  | 
212 |  | -            "--output-dir",  | 
213 |  | -            &format!("{}", output_dir.display()),  | 
 | 243 | +            "target/debug/cargo-gpu".as_ref(),  | 
 | 244 | +            "build".as_ref(),  | 
 | 245 | +            "--shader-crate".as_ref(),  | 
 | 246 | +            shader_crate_path.as_os_str(),  | 
 | 247 | +            "--output-dir".as_ref(),  | 
 | 248 | +            output_dir.as_os_str(),  | 
214 | 249 |         ];  | 
215 | 250 |         if let Cli {  | 
216 | 251 |             command: Command::Build(build),  | 
 | 
0 commit comments