Skip to content

Stop passing an invalid target to llvm-mingw's cross-compilation wrappers #1495

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

AlexTMjugador
Copy link

The cross-compilation toolchains distributed by the llvm-mingw project for building code for the *-pc-windows-gnullvm targets have a wrapper script in place of their clang binaries that calls them with a specific target, much like it has been the case with the Android NDK. When cc-rs sets a explicit --target flag, the wrapper script breaks down, and is no longer able to use the proper linker and libraries.

To improve on this situation and make it possible to cross-compile Rust projects that depend on building C code with cc-rs, let's skip passing this flag when cross-compilation with such a wrapper script is attempted.

…appers

The cross-compilation toolchains distributed by the `llvm-mingw` project
for building code for the `*-pc-windows-gnullvm` targets have a wrapper
script in place of their `clang` binaries that calls them with a
specific target, much like it has been the case with the Android NDK.
When `cc-rs` sets a explicit `--target` flag, the wrapper script breaks
down, and is no longer able to use the proper linker and libraries.

To improve on this situation and make it possible to cross-compile Rust
projects that depend on building C code with `cc-rs`, let's skip passing
this flag when cross-compilation with such a wrapper script is
attempted.
Copy link
Collaborator

@NobodyXu NobodyXu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, just wonder if the script detection can be more robust.

And it would be great if you can add a test for this

Comment on lines +4191 to +4194
fn is_llvm_mingw_wrapper(clang_path: &Path) -> bool {
if let Some(filename) = clang_path
.file_name()
.and_then(|file_name| file_name.to_str())
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a more robust way of testing?

I.e. checking version etc?

Copy link
Author

@AlexTMjugador AlexTMjugador Jul 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the review! I agree that a more robust detection method could be nice.

After taking a closer look at the llvm-mingw repository, it appears that this cross-compilation toolchain has setting a target since its very first tagged release, 20181017.

For Unix host platforms, the wrapper script has consistently been symlinked from x86_64-w64-mingw32-clang and similar names, so the toolchain has been quite consistent in this regard. As a result, checking its version doesn't seem necessary.

Interestingly, running x86_64-w64-mingw32-clang -v on any version of the toolchain reports the default target as x86_64-w64-windows-gnu. This doesn't exactly match either x86_64-pc-windows-gnu or x86_64-w64-mingw32, but it still seems to work just fine. (Why are LLVM's target names so inconsistent? 😅 I don't think I'd want to rely on the reported target for any important decisions on cc-rs...)

That said, aside from the target string oddities, this is a fairly standard LLVM toolchain with varying standard LLVM versions that aren't particularly distinct from stock LLVM. I don't think it's worth running any command with potentially brittle output or implement any extra complexity to determine whether to skip passing a target parameter in this case.

Instead, I figured we could check whether the compiler path is a symlink to a clang-target-wrapper.sh script. If and only if it is, we return true in this function. This approach should have a negligible chance of false positives, and in the unforeseen case that something goes wrong, users still have a fallback option other than fiddling with compiler flags: modifying the wrapper script directly.

What do you think?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants