Open-source project
mstorsjo/llvm-mingw avatar
mstorsjo/llvm-mingw

llvm-mingw: a Clang/LLD toolchain that targets all four Windows architectures

An LLVM/Clang/LLD based mingw-w64 toolchain

2,974 stars273 forksCNOASSERTION

At a glance

What is it?
llvm-mingw replaces binutils with LLVM tools in a mingw-w64 toolchain, giving one compiler that can target i686, x86_64, armv7 and arm64, and a Windows on ARM path that GCC does not offer. Here is how it installs, what it breaks, and who should stay on GCC.
Who is it for?
Adopt llvm-mingw if you need Windows on ARM targets, PDB debug info, or a single toolchain covering i686, x86_64, armv7 and arm64, and if your dependency tree does not depend on libtool linking C++ or on GNU linker scripts. Stay on a GCC/binutils mingw-w64 toolchain if you must link object files or static libraries produced elsewhere, or if you target pre-Vista Windows.
Can I use it commercially?
Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
Is it still maintained?
Yes. The repository received new commits within the last day.
What is it written in?
Mainly C, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 30, 2026, and from our analysis. They are not legal advice.

Editorial analysis

The Windows on ARM gap that llvm-mingw fills

GCC supports ARM and ARM64 as architectures, but not Windows on ARM, so a GCC based mingw-w64 toolchain cannot produce arm64 Windows binaries. llvm-mingw can, and it does so from the same installation that targets i686, x86_64 and armv7. That is the concrete reason the project exists: one toolchain directory, four target triples, instead of four separately built compiler binaries. The README also lists PDB debug info generation, Address Sanitizer and Undefined Behaviour Sanitizer support, and Control Flow Guard via the `-mguard=cf` compile and link flags as benefits since LLVM 16. The audience is narrow but real: people cross compiling Windows software from Linux or macOS, people shipping arm64 Windows builds, and people who want Clang's diagnostics and sanitizers on a Windows target without adopting MSVC. If you only build x86_64 Windows binaries and your current GCC mingw-w64 setup links cleanly, the README offers no argument that would make you switch.

How the toolchain is assembled: build scripts, wrappers and two CRTs

The repository is a recipe, not a compiler. `build-all.sh` drives a sequence of standalone shell scripts, and the Dockerfile shows the order that matters: `build-llvm.sh` first, then `build-lldb-mi.sh`, `strip-llvm.sh`, `install-wrappers.sh`, `build-mingw-w64.sh`, `build-mingw-w64-tools.sh`, `build-compiler-rt.sh`, `build-libcxx.sh`, `build-mingw-w64-libraries.sh`, a second `build-compiler-rt.sh` pass with `--build-sanitizers`, and finally `build-openmp.sh`. The comment in the Dockerfile explains why: the mingw runtime has to exist before the compiler-rt, libunwind, libcxxabi and libcxx runtimes are built. The wrappers directory is what makes a single toolchain answer to all four architectures; `install-wrappers.sh` installs the target-prefixed driver names. Two CRT choices exist. UCRT is the primary target, preinstalled since Windows 10 and installable on Vista or newer, and it is the only CRT under which Address Sanitizer works properly. msvcrt produces binaries against the msvcrt.dll that ships in every Windows version, which helps on old systems but is described in the README as generally less featureful. The Dockerfile defaults to `ARG DEFAULT_CRT=ucrt` and `ARG TOOLCHAIN_ARCHS="i686 x86_64 armv7 aarch64 arm64ec"`, so a container build covers five target names out of the box.

Installing llvm-mingw and building the toolchain from source

The README states that the GitHub Releases page contains prebuilt toolchains that can be downloaded and installed by just unpacking them, so there is no package manager step for the release archives. Cross compilers are named `llvm-mingw-<version>-<crt>-ubuntu-<distro_version>-<arch>.tar.xz` and run on Linux, while native toolchains are named `llvm-mingw-<version>-<crt>-<arch>.zip` and run on Windows. Both forms can compile for any of the four architectures. If you would rather build it, the README gives two entry points. The first compiles the toolchain for installation in the current Unix environment, fetching sources as needed:

bash
./build-all.sh <target-dir>

The second builds it reproducibly into a Docker image:

bash
docker build .

Individual components can be rebuilt by running the standalone shell scripts listed within `build-all.sh`. The README warns about two things here. If the source is already checked out, no effort is made to check out a different version when the build scripts have been updated to prefer one. And if configure flags in the `build-*.sh` scripts have changed, you might need to wipe the build directory under each project before the new options take effect. For MSYS2, the README says to install this package set with `pacman -S --needed`:

bash
git wget mingw-w64-x86_64-gcc mingw-w64-x86_64-ninja mingw-w64-x86_64-cmake make mingw-w64-x86_64-python3 autoconf libtool

Prebuilt Docker Linux images containing the toolchain are also available from Docker Hub under `mstorsjo/llvm-mingw`, and the README points at nightly builds with the very latest LLVM and mingw-w64 from git.

Where llvm-mingw breaks: libtool, linker scripts and mixed objects

The known issues section is unusually candid, and two entries will stop real builds. First, the toolchain uses a different CRT and C++ standard library than most mingw toolchains, so it is incompatible with object files and static libraries built with other toolchains. Mixing DLLs is supported only as long as CRT resources are not shared across the DLL boundary: no shared file handles, and memory must be freed by the DLL that allocated it. If your project links a vendor-provided static library, you need that library rebuilt with llvm-mingw. Second, libtool based projects containing C++ fail to link, typically with undefined symbols such as `___chkstk_ms`, `__alloca` or `___divdi3`. The README explains the mechanism: libtool runs `$CC -v`, picks out the default libraries, then invokes the linker driver with `-nostdlib` and names those libraries itself. It cannot detect that clang uses compiler_rt instead of libgcc, because clang passes an absolute path to a static library rather than a `-L` path plus `-l`. Clang is described as reluctant to change this, a libtool bug has been filed without a fix, and because libtool files are bundled inside each project's `configure` script, the workaround is per project: install and patch libtool and run `autoreconf -fi`, or patch the shipped `configure` by hand. Separately, LLD does not support linker scripts in its COFF part. The README notes that MinGW setups mostly use linker scripts to pass lists of object files, which response files can do instead, and that qmake moved to response files in v5.12.0. The llvm-rc replacement for windres is also described as not very mature and missing features GNU windres has.

Platform floor: UCRT, native TLS and Windows 7 assumptions

The default configuration targets Windows 7 with the Universal CRT. UCRT ships out of the box only since Windows 10, though it can be installed on Vista or newer, so binaries built with the default settings need either a modern Windows or an extra redistributable. The README states that the defaults can be changed in `build-mingw-w64.sh`, which means changing the floor is a rebuild, not a flag on the command line. Two further constraints push the floor up. The toolchain uses Windows native TLS, which does not work properly before Windows Vista, though code that does not use thread local variables is unaffected. The runtime libraries libunwind, libcxxabi and libcxx also assume Windows 7 or newer. Address Sanitizer is supported only on x86, so an arm64 build cannot use it as a substitute for testing. None of this matters for a project that already requires Windows 10, and all of it matters if you ship to industrial or embedded Windows installations. The msvcrt packages are the escape hatch for pre-Vista targets, at the cost of a less featureful CRT and no working Address Sanitizer.

llvm-mingw against a GCC/binutils mingw-w64 toolchain

The README is explicit that clang can be used as the compiler in a normal GNU binutils based environment, so the difference is the replacement of binutils with LLVM tools. That framing is the honest way to compare. A GCC/binutils mingw-w64 toolchain has a mature windres, a linker that accepts COFF linker scripts, and a CRT and C++ standard library that the wider ecosystem of prebuilt Windows libraries was compiled against. llvm-mingw trades those for arm64 Windows support, one installation covering four architectures, PDB debug info, sanitizers and Control Flow Guard. The practical decision rule follows from the known issues: if your build pulls in prebuilt static libraries or uses libtool for a C++ target, GCC/binutils costs you less. If you need arm64 Windows output, or you want sanitizers and PDBs on a Windows target, there is no equivalent in the GCC based mingw-w64 world, and the libtool workaround is a bounded, one-time patch per affected project. Note also that clang as a front end is not the differentiator here; the differentiator is LLD and the runtime libraries underneath it.

Release cadence, licence and what you are signing up for

Releases track LLVM closely. The three most recent are 20260922 with LLVM 23.1.2, 20260908 with LLVM 23.1.1 and 20260826 with LLVM 23.1.0, all dated within the last month, and the last push to the repository was on 2026-09-22. The README also points at a nightly tag with the very latest LLVM and mingw-w64 from git. That cadence has a cost: if you pin a release, you are on a known LLVM version, and if you build from source, `build-all.sh` fetches sources as needed and makes no effort to check out a different version when the scripts have been updated to prefer one. The README warns that if configure flags in the `build-*.sh` scripts change, you may need to wipe the build directory under each project before the new options take effect. Upgrading a source build is therefore not a matter of pulling and rerunning. On licensing, the repository metadata reports NOASSERTION and the tree contains `LICENSE.txt`; the toolchain bundles LLVM, mingw-w64 and runtime libraries that carry their own licences, so read `LICENSE.txt` and the upstream licences before redistributing a toolchain rather than assuming a single permissive grant. Nothing here is legal advice.

Editorial conclusion

Adopt llvm-mingw if you need Windows on ARM targets, PDB debug info, or a single toolchain covering i686, x86_64, armv7 and arm64, and if your dependency tree does not depend on libtool linking C++ or on GNU linker scripts. Stay on a GCC/binutils mingw-w64 toolchain if you must link object files or static libraries produced elsewhere, or if you target pre-Vista Windows. Before committing, verify that every prebuilt library you link was built with the same CRT and C++ standard library, and test your actual link line rather than a hello world.

Frequently asked questions

What is llvm-mingw?

It is a recipe for reproducibly building an LLVM, Clang and LLD based mingw-w64 toolchain, plus prebuilt toolchains on the GitHub Releases page that can be installed by unpacking them. The main difference from a normal mingw setup is that the binutils tools are replaced with LLVM based ones.

How to install llvm-mingw?

Download a prebuilt package from the GitHub Releases page and unpack it; cross compilers are named llvm-mingw-<version>-<crt>-ubuntu-<distro_version>-<arch>.tar.xz and native Windows toolchains are named llvm-mingw-<version>-<crt>-<arch>.zip. Prebuilt Docker Linux images are also available from Docker Hub under mstorsjo/llvm-mingw.

How to use llvm-mingw?

The README gives two build entry points: ./build-all.sh <target-dir> to compile the toolchain for installation in the current Unix environment, or docker build . to build it reproducibly into a Docker image. Individual components can be rebuilt by running the standalone shell scripts listed within build-all.sh.

What is the difference between the msvcrt and UCRT packages in llvm-mingw?

UCRT is the primary target, preinstalled since Windows 10 and installable on Vista or newer, and Address Sanitizer only works properly with it. The msvcrt variant produces binaries against msvcrt.dll, which is built into all Windows versions but is generally less featureful.

Official sources

  1. Issues
  2. mstorsjo/llvm-mingw on GitHub
  3. README
  4. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/mstorsjo-llvm-mingw.svg)](https://hysenlabs.com/projects/mstorsjo-llvm-mingw)