@@ -128,6 +128,8 @@ pub enum SpirvBuilderError {
128128 MetadataFileMissing ( #[ from] std:: io:: Error ) ,
129129 #[ error( "unable to parse multi-module metadata file" ) ]
130130 MetadataFileMalformed ( #[ from] serde_json:: Error ) ,
131+ #[ error( "cargo metadata error" ) ]
132+ CargoMetadata ( #[ from] cargo_metadata:: Error ) ,
131133}
132134
133135const SPIRV_TARGET_PREFIX : & str = "spirv-unknown-" ;
@@ -427,10 +429,11 @@ pub struct SpirvBuilder {
427429 /// [this RFC](https://rust-lang.github.io/rfcs/0131-target-specification.html).
428430 #[ cfg_attr( feature = "clap" , clap( skip) ) ]
429431 pub path_to_target_spec : Option < PathBuf > ,
430- /// Set the target dir path within `./target` to use for building shaders. Defaults to `spirv-builder`, resulting
431- /// in the path `./target/spirv-builder`.
432+ /// Set the target dir path to use for building shaders. Relative paths will be resolved
433+ /// relative to the `target` dir of the shader crate, absolute paths are used as is.
434+ /// Defaults to `spirv-builder`, resulting in the path `./target/spirv-builder`.
432435 #[ cfg_attr( feature = "clap" , clap( skip) ) ]
433- pub target_dir_path : Option < String > ,
436+ pub target_dir_path : Option < PathBuf > ,
434437
435438 // `rustc_codegen_spirv::linker` codegen args
436439 /// Change the shader `panic!` handling strategy (see [`ShaderPanicStrategy`]).
@@ -648,10 +651,11 @@ impl SpirvBuilder {
648651 self
649652 }
650653
651- /// Set the target dir path within `./target` to use for building shaders. Defaults to `spirv-builder`, resulting
652- /// in the path `./target/spirv-builder`.
654+ /// Set the target dir path to use for building shaders. Relative paths will be resolved
655+ /// relative to the `target` dir of the shader crate, absolute paths are used as is.
656+ /// Defaults to `spirv-builder`, resulting in the path `./target/spirv-builder`.
653657 #[ must_use]
654- pub fn target_dir_path ( mut self , name : impl Into < String > ) -> Self {
658+ pub fn target_dir_path ( mut self , name : impl Into < PathBuf > ) -> Self {
655659 self . target_dir_path = Some ( name. into ( ) ) ;
656660 self
657661 }
@@ -932,34 +936,21 @@ fn invoke_rustc(builder: &SpirvBuilder) -> Result<PathBuf, SpirvBuilderError> {
932936 rustflags. extend ( extra_rustflags. split_whitespace ( ) . map ( |s| s. to_string ( ) ) ) ;
933937 }
934938
935- // If we're nested in `cargo` invocation, use a different `--target-dir`,
936- // to avoid waiting on the same lock (which effectively dead-locks us).
937- let outer_target_dir = match ( env:: var ( "PROFILE" ) , env:: var_os ( "OUT_DIR" ) ) {
938- ( Ok ( outer_profile) , Some ( dir) ) => {
939- // Strip `$outer_profile/build/*/out`.
940- [ & outer_profile, "build" , "*" , "out" ] . iter ( ) . rev ( ) . try_fold (
941- PathBuf :: from ( dir) ,
942- |mut dir, & filter| {
943- if ( filter == "*" || dir. ends_with ( filter) ) && dir. pop ( ) {
944- Some ( dir)
945- } else {
946- None
947- }
948- } ,
949- )
950- }
951- _ => None ,
939+ let target_dir_path = builder
940+ . target_dir_path
941+ . clone ( )
942+ . unwrap_or_else ( || PathBuf :: from ( "spirv-builder" ) ) ;
943+ let target_dir = if target_dir_path. is_absolute ( ) {
944+ target_dir_path
945+ } else {
946+ let metadata = cargo_metadata:: MetadataCommand :: new ( )
947+ . current_dir ( path_to_crate)
948+ . exec ( ) ?;
949+ metadata
950+ . target_directory
951+ . into_std_path_buf ( )
952+ . join ( target_dir_path)
952953 } ;
953- // FIXME(eddyb) use `crate metadata` to always be able to get the "outer"
954- // (or "default") `--target-dir`, to append `/spirv-builder` to it.
955- let target_dir = outer_target_dir. map ( |outer| {
956- outer. join (
957- builder
958- . target_dir_path
959- . as_deref ( )
960- . unwrap_or ( "spirv-builder" ) ,
961- )
962- } ) ;
963954
964955 let profile = if builder. release { "release" } else { "dev" } ;
965956
@@ -1014,10 +1005,7 @@ fn invoke_rustc(builder: &SpirvBuilder) -> Result<PathBuf, SpirvBuilderError> {
10141005 . arg ( builder. shader_crate_features . features . join ( "," ) ) ;
10151006 }
10161007
1017- // NOTE(eddyb) see above how this is computed and why it might be missing.
1018- if let Some ( target_dir) = target_dir {
1019- cargo. arg ( "--target-dir" ) . arg ( target_dir) ;
1020- }
1008+ cargo. arg ( "--target-dir" ) . arg ( target_dir) ;
10211009
10221010 // Clear Cargo environment variables that we don't want to leak into the
10231011 // inner invocation of Cargo (because e.g. build scripts might read them),
0 commit comments