Search code examples
mingwmingw-w64msys2msys

What are MSYS2 environments? How do I pick one?


MSYS2 is said to have different environments.

What are they? How do I choose which one to use? What's the difference between MINGW64 and UCRT64?


(This Q&A is intended as a canonical duplicate on this topic.)


Solution

  • See the official manual. Following environments are available: UCRT64, MINGW64, CLANG64, MSYS, and others (see link).

    UCRT64 is a good default, MINGW64 is popular too, but the alternatives are explained below.

    The different environments exist to produce different kinds of Windows executables, or do that with different tools.

    Each environment has its own packages (compilers, precompiled libraries, and various executables), which can be distinguished by the common prefix in the package names (e.g. mingw-w64-ucrt-x86_64-... for UCRT64).

    Each environment installs its files to a separate subdirectory inside the MSYS2 installation, e.g. UCRT64 installs to C:\msys64\ucrt64, and so on (except MSYS notably installs to C:\msys64\usr, and some packages directly to C:\msys64).

    Each environment has the respective shortcut in the Start menu, which starts the MSYS2 terminal and adds the respective directory to its PATH. E.g. the MSYS2 UCRT64 starts with C:\msys64\ucrt64\bin in the PATH.

    • By default MSYS2 ignores the system-wide PATH setting, and starts its terminal with a fully customized PATH, run echo $PATH to see it.

    • All environments also add C:\msys64\usr\bin to PATH after C:\msys64\<env>\bin. So, in a way, all environments inherit from the MSYS environment. More on that below.

    • The environments also customize some other environment variables, run printenv to see for yourself.

    MSYS2 terminal displays the current environment in magenta text in the terminal prompt.

    How do I use a specific environment?

    1. All packages you install must have their name prefixed appropriately. E.g. for UCRT64, mingw-w64-ucrt-x86_64-... (see the table below for other environments).

      This applies to all compilers, libraries, etc. So if you want to install GCC in UCRT64, use pacman -S mingw-w64-ucrt-x86_64-gcc, NOT pacman -S gcc.

      The only exception are utilites ported from Linux which are unrelated to the compilation process, such as grep, sed, bash, etc, which don't have prefixed packages.

      Unprefixed packages all belong to the MSYS environment.

      WARNING: Normally you can install packages for multiple environments, and they won't interfere with each other, except the unprefixed MSYS packages are in the PATH for all the environments, and some of them will get in your way. E.g if you install pacman -S gcc, forget to install pacman -S ...-gcc, then try to run gcc from any environment other than MSYS, you'll call GCC of the MSYS environment, instead of your environment's GCC. Most of the time this is not what you want, and you'll get cryptic errors.

      (The notable exception is make, its prefixed and unprefixed packages use different executable names, so they don't conflict, can be installed at the same time, and both are viable options. The prefixed version (which installs as mingw32-make) works much faster, but the unprefixed one offers better Linux compatibility by having its path functions return Linux-style paths.)

    2. If you use MSYS2 terminal, start the terminal using the appropriate shortcut.

      The shortcuts have the environment names in them, e.g. for UCRT64 use the MSYS2 UCRT64 shortcut.

    3. If you don't use the MSYS2 terminal and call the tools from elsewhere, add the appropriate directory to PATH, e.g. for UCRT64 add C:\msys64\ucrt64\bin.

      In rare cases you may also need to add C:\msys64\usr\bin. If you do, make sure to add it after the previously mentioned directory.

      To avoid problems, it's a good idea to have those directories directly at the beginning of the PATH. There are two PATH settings, system-wide and per-user; use the former as it has priority over the latter.

    How do I choose the environment?

    UCRT64 should be a good default for most purposes.

    Otherwise the choice depends on:

    • Preferred compiled: GCC or Clang (some provide both).
    • Preferred C++ standard library (GCC's libstdc++ or Clang's libc++, some provide both).
    • Preferred C standard library (the old MSVCRT, or the new UCRT with the UTF-8 support).
    • Whether you need the sanitizers (Address Sanitizer, UB sanitizer, etc).
    • Whether you need Cygwin-style POSIX emulation.
    • Whether you want to produce executables for ARM.
    Environment UCRT64 MINGW64 CLANG64 MSYS
    Installs to
    (relative to MSYS2 installation
    directory, normally C:\msys64\...)
    /ucrt64 /mingw64 /clang64 /usr
    (some packages to /?)
    Package prefix mingw-w64-ucrt-x86_64- mingw-w64-x86_64- mingw-w64-clang-x86_64- none
    Target architecture x86_64 x86_64 x86_64 Cygwin x86_64
    Compiler GCC (also Clang) GCC (also Clang) Clang GCC (also Clang)
    (might be outdated)
    C++ standard library libstdc++ (also libc++) libstdc++ (also libc++) libc++ libstdc++
    C standard library UCRT MSVCRT UCRT Cygwin
    Sanitizers No1 No1 YES No1

    1 — UBSan can be made to work, but it can't print diagnostics and can only crash on error.

    Target architecture variants:

    • 32-bit

      All environments above produce x64 executables (aka x86_64).

      There are also environments for x32 executables (aka i686): MINGW32 and CLANG32.

      They are similar to the respective x64 environments, except the files are installed to the /...32 directories instead of /...64, and the package prefixes contain i686 in place of x86_64.

    • ARM

      All environments above produce executables for x86, either x32 or x64. This is what the majority of desktops and laptops run on.

      Apparently there are now some ARM laptops running Windows too. And while they can emulate x86 to run x86 apps, native ARM applications should have better performance.

      The CLANGARM64 environment can be used to produce ARM (aka aarch64) apps. It's similar to CLANG64, except the files are installed to /clangarm64, and the packages are prefixed with mingw-w64-clang-aarch64-.

    C standard libraries, MSVCRT vs UCRT:

    The manual explains the difference well.

    In short:

    • MSVCRT (msvcrt.dll):

      • Old, comes from Microsoft Visual Studio 6.0.

      • This was the only option for MinGW until a few years ago.

      • No UTF-8 support for paths, must use UTF-16 and wchar_t to handle unicode in paths.

    • UCRT (ucrtbase.dll)

      • New and shiny, this is what the contemporary Visual Studio uses.

      • Available by default on Windows 10, on prior Windows versions must be installed manually.

      • Supports UTF-8 in paths, if you enable a UTF-8 locale in your application.

    The MSYS environment:

    This environment is based on MSYS2's own fork of Cygwin, which is a POSIX emulation layer.

    It's primarily used to compile Linux applications that were not written in a cross-platform manner. Arguably, new applications should always be written in a cross-platform manner in the first place, and then compiled using the other environments.

    MSYS2 uses it to provide bash, grep, sed, awk, and other command line utilities commonly used on Linux.

    From my limited understanding, MSYS applications are normally used exclusively inside of the MSYS2 shell for development purposes, and not distrbuted to users.

    Among other things, applications compiled with it see all paths in Linux style: with forward slashes / as separators, with the / (root) directory mapped to the MSYS2 installation directory, and /c magically mapped to C:\ (similary for other drive letters). They also get access to emulated Linux-specific functions, such as fork().

    This emulation layer has a performance cost.

    It should also be noted that MSYS seems to not provide as much libraries (and packages in general) as the other environments, and doesn't receive compiler updates as frequently.