Change:
return; } <ins> if let Some(config) = builder.config.target_config.get(&target) { if config.llvm_config.is_some() { // If the LLVM was externally provided, then we don't currently copy // artifacts into the sysroot. This is not necessarily the right // choice (in particular, it will require the LLVM dylib to be in // the linker's load path at runtime), but the common use case for // external LLVMs is distribution provided LLVMs, and in that case // they're usually in the standard search path (e.g., /usr/lib) and // copying them here is going to cause problems as we may end up // with the wrong files and isn't what distributions want. // // This behavior may be revisited in the future though. return; } } </ins> // On macOS, rustc (and LLVM tools) link to an unversioned libLLVM.dylib // instead of libLLVM-11-rust-....dylib, as on linux. It's not entirely // clear why this is the case, though. llvm-config will emit the versioned

Discussion:
Since 1.48 beta, is now installing even when dynamically linking against the system one. Not only that, the install path is unaware of the target architecture, which breaks during cross-compiling. I am not sure exactly what happens - possibly (a) the host is installed instead of the target or (b) both are installed, and the host clobbers the target - in any case the end result I observe is that the host-arch ends up in the install directory instead of the target-arch one, which would be correct.
Possibly to do with the new RustDev component and especially this snippet: This is a regression; 1.47 had the correct behaviour of not trying to install LLVM at all. Note that I am not explicitly referencing RustDev at all, I am just calling .
I plan to investigate fixing this soon, I think it's important we get this fixed. Could you provide instructions on how to verify things are working so I can check locally? (I guess I can compare against a 1.47 build but would be good to get what command you're running).
in ~ then with , the tarballs shouldn't contain a but they do. The documentation for llvm-config says "Note that if this is specified we don't compile LLVM at all for this target." - so possibly this bug can be fixed simply by changing this snippet in : to check for whether was set or not.
The cross-compiling wrong-location/clobbering issue still exists as I described in the OP, but it does not affect my use-case since we're not installing On Debian we are in fact moving everything from to after , but I am not sure how cross-platform this is for you to adopt. I'm also not sure why it is the specifically that ends up with the wrong architecture, but the other libraries (e.g. ) are fine.
I think it was actually 's commit that changed this, specifically around here: Before, we would only copy if it was found in the . Now it copies everything that says, even if that is external. I also see that has a short path for custom : I think it would work to change to skip out on custom , as suggests.
Though one could argue that is wrong (in some cases) right? That is, if you don't copy, it'll not work unless the original location is in LDLIBRARYPATH or equivalent.

I'd be fine changing/reverting to not copy on custom llvm though, that seems like the right fix for now - it seems rare to have custom LLVM and want the copy.
Filed with the suggested fix here.
I see it the same as any other system library that we might link against. e.g. Cargo links to the system openssl by default, and we don't try to pull that into dist tarballs.
Good point :)