How to check that the current compiler is GCC/MSYS when using Ninja generator?

Problem Descriptions

There is a variable called MSYS, which is set True when we’re using MSYS Makefiles generator. However, it will be EMPTY if we’re using Ninja or Ninja Multi-Config generator.

I’m wondering that is there any other methods that can help us to check whether the current compiler is GCC/MSYS (C:\msys64\usr\bin\gcc.exe) when using Ninja or Ninja Multi-Config generator?

Does CMAKE_CXX_COMPILER_ID help?

According to the documentation MSYS just indicates which make and command line interpreter is used. It’s not saying that you compiler targets for an MSYS environment.
AFAIK you can do also crosscompilation in MSYS. So using that before seems to be wrong.

I would expect CMAKE_SYSTEM_NAME to hold that kind of information (and the corresponding $<PLATFORM_ID> generator expression)

Actually, there is an idea which is using the output of gcc -dumpmachine. (from this issue)

  • For GCC/MSYS, it will print: x86_64-pc-msys.
  • For GCC/MINGW32, it will print: i686-w64-mingw32.
  • For GCC/MINGW64, it will print: x86_64-w64-mingw32.

But is there any built-in mechanism in CMake that can differentiate GCC/MSYS from the others?

@brad.king

Based on what you said in this issue:

If you want to build for the cygwin- or msys2-runtime libraries, instead of MinGW, you need to use a CMake that’s built for them too. MSYS2 and Cygwin both have packages for that.

And it actually worked. The CMAKE_SYSTEM_NAME will be evaluated to “MSYS” when using the CMake (/c/msys64/usr/bin/cmake.exe) installed on MSYS.

However, I wondered how to judge the GCC currently used is MSYS2-based when using the CMake (C:\Program Files\CMake\bin\cmake.exe) installed on Windows?

Prerequisites

pacman -S base-devel
pacman -S gcc
pacman -S cmake
pacman -S ninja

Demonstration

  • Example CMakeLists.txt

    cmake_minimum_required(VERSION 3.20)
    project(cmake-windows LANGUAGES C CXX)
    message("CMAKE_COMMAND = ${CMAKE_COMMAND}")
    message("CMAKE_SYSTEM_NAME = ${CMAKE_SYSTEM_NAME}")
    
  • Example CMakePresets.json

    Click to expand
    {
      "version": 4,
      "configurePresets": [
        {
          "name": "msys2-gcc-x64-ninja-debug",
          "displayName": "MSYS2 GCC x64 (Ninja) Debug",
          "description": "Using GCC x64 compiler with \"Ninja\" geneartor on MSYS2 - Debug",
          "generator": "Ninja",
          "binaryDir": "${sourceDir}/build/${presetName}",
          "installDir": "${sourceDir}/install/${presetName}",
          "environment": {
            "PATH": "/c/msys64/usr/bin:$penv{PATH}"
          },
          "cacheVariables": {
            "CMAKE_C_COMPILER": "gcc.exe",
            "CMAKE_CXX_COMPILER": "g++.exe",
            "CMAKE_BUILD_TYPE": "Debug"
          }
        }
      ]
    }
    
  • Example Terminal Log on MSYS shell

    Click to expand
    hwhsu1231@vvb-windows MSYS /f/GitRepo/cmake-windows-preset
    $ cmake --preset msys2-gcc-x64-ninja-debug
    Preset CMake variables:
    
      CMAKE_BUILD_TYPE="Debug"
      CMAKE_CXX_COMPILER="g++.exe"
      CMAKE_C_COMPILER="gcc.exe"
      CMAKE_INSTALL_PREFIX:PATH="/f/GitRepo/cmake-windows-preset/install/msys2-gcc-x64-ninja-debug"
    
    Preset environment variables:
    
      PATH="/c/msys64/usr/bin:/usr/local/bin:/usr/bin:/bin:/opt/bin:/c/Windows/System32:/c/Windows:/c/Windows/System32/Wbem:/c/Windows/System32/WindowsPowerShell/v1.0/:/usr/bin/site_perl:/usr/bin/vendor_perl:/usr/bin/core_perl"
    
    -- The C compiler identification is GNU 11.3.0
    -- The CXX compiler identification is GNU 11.3.0
    -- Detecting C compiler ABI info
    -- Detecting C compiler ABI info - done
    -- Check for working C compiler: /c/msys64/usr/bin/gcc.exe - skipped
    -- Detecting C compile features
    -- Detecting C compile features - done
    -- Detecting CXX compiler ABI info
    -- Detecting CXX compiler ABI info - done
    -- Check for working CXX compiler: /c/msys64/usr/bin/g++.exe - skipped
    -- Detecting CXX compile features
    -- Detecting CXX compile features - done
    CMAKE_COMMAND = /usr/bin/cmake.exe
    CMAKE_SYSTEM_NAME = MSYS
    -- Configuring done
    -- Generating done
    -- Build files have been written to: /f/GitRepo/cmake-windows-preset/build/msys2-gcc-x64-ninja-debug
    

@brad.king

Another thing I want to confirm is that:

Is it proper to use the CMake(C:\Program Files\CMake\bin\cmake.exe) installed on Windows when compiling with the following compilers?

  • GCC/MINGW32
  • GCC/MINGW64
  • GCC/UCRT64
  • CLANG/CLANG32
  • CLANG/CLANG64
  • CLANG/CLANGARM64

If the target platform is Windows, regardless of whether the target ABI is GNU-style (MinGW) or MSVC-style, then the C:\Program Files\CMake\bin\cmake.exe tool should work. It’s only when targeting cygwin’s or msys2’s runtime environments that one needs a CMake built for them, and such a CMake won’t work for targeting Windows. These platforms are all independent of each other and tooling cannot be mixed among them.

@brad.king

Is there any other differences or effects between using CMake installed on Windows and MSYS2?

The only differences that I found are:

  • CMAKE_SYSTEM_NAME, which will print:

    • Windows with the former.
    • MSYS with the latter.
  • Path Seperators, which will use:

    • Semicolon (;) and Backslash (\) with the former.
    • Colon (:) and Slash (/) with the latter.

Because it seems that I can actually compile an executable when using C:\Program Files\CMake\bin\cmake.exe with C:\msys64\usr\bin\gcc.exe compiler.

I wondered what else effects?