11

I want to build my C++ applications from the Windows PowerShell command line using CMake and MinGW.

When I do this in the "normal way," with these commands:

mkdir build
cd build
cmake ..
make

CMake chooses Visual Studio as the default compiler, and doesn't generate any Makefiles for me.

I want CMake to use MinGW as the default compiler, and generate Makefiles. It works exactly the way that I want it to when I run these commands, adding the -G "MinGW Makefiles" flag:

mkdir build
cd build
cmake .. -G "MinGW Makefiles"
make

How can I make CMake behave this way all the time, without adding the -G "MinGW Makefiles" flag?

I've tried setting up a CMAKE_GENERATOR environment variable in Windows, and pointing it to "path\to\mingw\bin", "path\to\mingw\bin\mingw32-make.exe", as well as a string that reads "MinGW Makefile".

None of these worked for me after running refreshenv and then trying to run cmake .. again.

Does anybody know if this is the correct environment variable to use in order to specify CMake's default behavior? If it is, what value should I be using?

Soren Richenberg
  • 113
  • 1
  • 1
  • 5
  • Just add MinGW to the PATH variable and then try this `find_program(CMAKE_CXX_COMPILER NAMES $ENV{CXX} g++ PATHS ENV PATH NO_DEFAULT_PATH)` – NutCracker Nov 28 '19 at 21:10
  • According to [that answer](https://stackoverflow.com/a/6439664/3440745) there is no a variable which could affect on the [generator](https://cmake.org/cmake/help/v3.9/manual/cmake-generators.7.html) used by default in CMake. But according to that [bugreport](https://gitlab.kitware.com/cmake/cmake/issues/16339) the things could be changed.. in the future. – Tsyvarev Nov 28 '19 at 21:16
  • I think that what are you asking is wrong... the `CMakeFiles.txt` should be agnostic about the compiler as much as possible... this allows you to the same project for different generators. – Elvis Dukaj Mar 27 '20 at 13:46
  • Create an alias? An old doskey macro or alternatively a batch file cmake.bat which forwards all arguments and injects the generator first? – André Jun 01 '21 at 20:30

3 Answers3

7

How can I make CMake behave this way all the time, without adding the -G "MinGW Makefiles" flag?

You can't, not in any version of CMake released to date. CMake chooses a generator before it starts evaluating any CMakeLists.txt files. By default, it chooses a generator based on runtime platform and available toolsets, and command-line options are the only way presently available to influence or override CMake's choice of generator.

In comments, @Tsyvarev pointed out an open CMake issue report asking for the very same feature you are asking for. The associated comment thread provides more detail, and the last comment was earlier this year. I would guess that eventually CMake will add support for specifying a generator via environment variable, but for now, your -G option is the only available alternative. You could consider scripting it if you want to save keystrokes and reduce the risk of typos.

John Bollinger
  • 160,171
  • 8
  • 81
  • 157
2

cmake uses Visual Studio generator for MinGW on Windows by default (even without Visual Studio!), this is the real annoying issue (Cygwin is not affected).

We need to work around MinGW only. What will be the most reliable hook for MinGW? I think MSYSTEM is very popular environment variable that will always be defined for MinGW.

You can place PreLoad.cmake in the project root with the following content:

if (NOT "$ENV{MSYSTEM}" STREQUAL "" AND "$ENV{VisualStudioVersion}" STREQUAL "")
  find_program (CMAKE_NINJA_BINARY NAMES "ninja")
  if (CMAKE_NINJA_BINARY)
    set (
      CMAKE_GENERATOR "Ninja"
      CACHE INTERNAL "Cmake generator"
    )
    return ()
  endif ()

  find_program (CMAKE_MAKE_BINARY NAMES "gmake" "make")
  if (CMAKE_MAKE_BINARY)
    set (
      CMAKE_GENERATOR "Unix Makefiles"
      CACHE INTERNAL "Cmake generator"
    )
    return ()
  endif ()
endif ()

Unfortunately this solution is not universal:

MSYSTEM=MINGW64 cmake -G "Unix Makefiles" ..
    CMake Error: Error: generator : Unix Makefiles
    Does not match the generator used previously: Ninja
    Either remove the CMakeCache.txt file and CMakeFiles directory or choose a different binary directory.

If you are setting CMAKE_GENERATOR inside PreLoad.cmake than you are loosing ability to use -G cmake option. If you don't need this option, than this solution will be just fine.

PS It is not possible to access -G option value inside PreLoad.cmake as CMAKE_GENERATOR or another option. So it is not possible to add guard case like NOT DEFINED CMAKE_GENERATOR to check whether generator has been provided explicitly using -G option.

puchu
  • 3,294
  • 6
  • 38
  • 62
2

I know this is late. but in case someone came here and find this answer useful
all you have to do is to create a function something like this:

function gcmake {cmake .. -G "MinGW Makefiles"}

then you can simply type

mkdir build
cd build
gcmake ..
make

tip: you can add this function to your profile so that it will be saved to any new session. you can follow this nice guide

mody
  • 56
  • 2