@@ -147,16 +147,39 @@ fn invoke_rustc(builder: &SpirvBuilder) -> Result<PathBuf, SpirvBuilderError> {
147
147
rustc_codegen_spirv. display( ) ,
148
148
feature_flag,
149
149
) ;
150
- let build = Command :: new ( "cargo" )
151
- . args ( & [
152
- "build" ,
153
- "--message-format=json-render-diagnostics" ,
154
- "-Z" ,
155
- "build-std=core" ,
156
- "--target" ,
157
- "spirv-unknown-unknown" ,
158
- "--release" ,
159
- ] )
150
+ let mut cargo = Command :: new ( "cargo" ) ;
151
+ cargo. args ( & [
152
+ "build" ,
153
+ "--message-format=json-render-diagnostics" ,
154
+ "-Z" ,
155
+ "build-std=core" ,
156
+ "--target" ,
157
+ "spirv-unknown-unknown" ,
158
+ "--release" ,
159
+ ] ) ;
160
+
161
+ // If we're nested in `cargo` invocation, use a different `--target-dir`,
162
+ // to avoid waiting on the same lock (which effectively dead-locks us).
163
+ // This also helps with e.g. RLS, which uses `--target target/rls`,
164
+ // so we'll have a separate `target/rls/spirv-builder` for it.
165
+ if let ( Ok ( profile) , Some ( mut dir) ) = (
166
+ env:: var ( "PROFILE" ) ,
167
+ env:: var_os ( "OUT_DIR" ) . map ( PathBuf :: from) ,
168
+ ) {
169
+ // Strip `$profile/build/*/out`.
170
+ if dir. ends_with ( "out" )
171
+ && dir. pop ( )
172
+ && dir. pop ( )
173
+ && dir. ends_with ( "build" )
174
+ && dir. pop ( )
175
+ && dir. ends_with ( profile)
176
+ && dir. pop ( )
177
+ {
178
+ cargo. arg ( "--target-dir" ) . arg ( dir. join ( "spirv-builder" ) ) ;
179
+ }
180
+ }
181
+
182
+ let build = cargo
160
183
. stderr ( Stdio :: inherit ( ) )
161
184
. current_dir ( & builder. path_to_crate )
162
185
. env ( "RUSTFLAGS" , rustflags)
0 commit comments