Home

Awesome

LLVM MinGW

This is a recipe for reproducibly building a LLVM/Clang/LLD based mingw-w64 toolchain.

Benefits of a LLVM based MinGW toolchain are:

Clang on its own can also be used as compiler in the normal GNU binutils based environments though, so the main difference lies in replacing binutils with LLVM based tools.

Releases

The GitHub Releases page contains prebuilt toolchains that can be downloaded and installed by just unpacking them.

They come primarily in two different forms; packages named llvm-mingw-<version>-<crt>-ubuntu-<distro_version>-<arch>.tar.xz are cross compilers, that can be run on Linux, compiling binaries for any of the 4 target Windows architectures. Packages named llvm-mingw-<version>-<crt>-<arch>.zip are native toolchains that run on Windows (with binaries in the specified architecture), but which all can compile binaries for any of the 4 architectures.

The cross compilers come in versions running on either x86_64 or aarch64. (They're built on Ubuntu, but hopefully do run on other contempory distributions as well.)

There are packages with two different choices of CRT (C runtime) - the primary target is UCRT (the Universal C Runtime). The UCRT is available preinstalled since Windows 10, but can be installed on top of Vista or newer. The other legacy alternative is msvcrt, which produces binaries for (and uses) msvcrt.dll, which is a built-in component in all versions of Windows. This allows running directly out of the box on older versions of Windows too, without ensuring that the UCRT is installed, but msvcrt.dll is generally less featureful. Address Sanitizer only works properly with UCRT.

In addition to the downloadable toolchain packges, there are also prebuilt docker linux images containing the llvm-mingw toolchain, available from Docker Hub.

Building from source

The toolchain can be compiled for installation in the current Unix environment, fetching sources as needed:

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

To reduce the size of the installation, removing some files that aren't necessary after building, run:

./strip-llvm.sh <target-dir>

It can also be built, reproducibly, into a Docker image:

docker build .

Individual components of the toolchain can be (re)built by running the standalone shellscripts listed within build-all.sh. However, if the source already is checked out, no effort is made to check out a different version (if the build scripts have been updated to prefer a different version) - and likewise, if configure flags in the build-*.sh scripts have changed, you might need to wipe the build directory under each project for the new configure options to be taken into use.

Building in MSYS2

To build in MSYS2, install the following set of packages with pacman -S --needed:

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

Status

The toolchain currently does support both C and C++, including support for exception handling.

It is in practice new and hasn't been tested with quite as many projects as the regular GCC/binutils based toolchains yet. You might run into issues building non-trivial projects.

Known issues

LLD, the LLVM linker, is what causes most of the major differences to the normal GCC/binutils based MinGW.

Additionally, one may run into other minor differences between GCC and clang.

PDB support

LLVM does support generating debug info in the PDB format. Since GNU binutils based mingw environments don't support this, there's no predecent for what command line parameters to use for this, and llvm-mingw produces debug info in DWARF format by default.

To produce debug info in PDB format, you currently need to do the following changes:

Even though LLVM supports this, there are a few caveats with using it when building in MinGW mode: