Repository navigation
LLVM bakes a mingw triple into a compiler that targets MSVC - #320
Merged
Merged
Conversation
A mojo.exe built for Windows thinks its default target is x86_64-w64-windows-gnu. Ask it for LLVM IR and the module header says so, on a build where the C toolchain, the Mojo compiler flags and the sysroot all say x86_64-pc-windows-msvc. The triple comes from LLVM's own Bazel files. config.bzl picks LLVM_HOST_TRIPLE and LLVM_DEFAULT_TARGET_TRIPLE out of a select, and the arm it lands on for us is is_x86_64_windows_clang_mingw, which is not a statement about mingw at all: the config_setting behind it is Windows, x86_64, and a compiler that calls itself clang. Ours does, because it is clang. LLVM reads that as a claim about the ABI, on the assumption that clang on Windows means the GNU driver and only clang-cl means MSVC, and we are the third case. Nothing notices until something asks the compiler to generate code without naming a target, which is what mojo run does. The code then wants ___chkstk_ms and __main, which are libgcc and mingw entry points, and the JIT cannot resolve them because a Windows machine has no reason to have either. Fixed in the same place as the stack flag patch, which is already there for the same reason and says so in its own comment. Saying clang-cl in our toolchain instead would also move the select, but it would move it by describing the driver as something it is not, and it would drop us off the arm the stack flag patch is attached to.
Owner
Author
|
Verified on a Windows host with a cross linked Before: After:
|
This was referenced Sep 9, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #318.
A
mojo.exebuilt for Windows thinks its default target isx86_64-w64-windows-gnu. Ask it for LLVM IR and the module header says so, on a build where the C toolchain passes--target=x86_64-pc-windows-msvc, the Mojo compiler passes-target-triple=x86_64-pc-windows-msvc, and the sysroot is the Microsoft one.The triple comes from LLVM's own Bazel files.
config.bzlpicksLLVM_HOST_TRIPLEandLLVM_DEFAULT_TARGET_TRIPLEout of a select, and the arm it lands on for us isis_x86_64_windows_clang_mingw. That name is misleading. Theconfig_settingbehind it is Windows, x86_64, and a compiler that calls itselfclang, and ours does, because it is clang. LLVM reads the name as a claim about the ABI on the assumption that clang on Windows means the GNU driver and onlyclang-clmeans MSVC, and we are the third case, which is the clang driver targeting MSVC.What it breaks
Nothing notices until something asks the compiler to generate code without naming a target on the command line, which is what
mojo rundoes. Then:___chkstk_msis libgcc's stack probe and__mainis the mingw static constructor hook. Neither has an MSVC equivalent to find, so no work on the JIT side fixes this. It is what blocks #31.The change
One line in the LLVM overlay, patched in the same place and for the same reason as
llvm_windows_stack_flag.patch, which already carries a comment saying that this arm means "Windows and clang" rather than "mingw".Only the x86_64 arm is changed. The aarch64 one above it has the same problem, but nothing here builds for that target, so there is no way to find out whether the triple is the only thing wrong with it.
Why not clang-cl
The other way to move the select is to say
compiler = "clang-cl"in our own toolchain, which is what the issue suggested before this was written. Two things against it. It describes the driver as something it is not, and it is a single value shared by every target, so it would also drop us off theis_windows_clang_mingwarm thatllvm_windows_stack_flag.patchattaches the Windows stack size and theole32,uuidandws2_32link flags to. It also does not land on an MSVC arm inconfig.bzl, because there is nois_x86_64_windows_clang_clentry in that select. It falls through to the plain Windows default, which happens to be close enough by accident.