55

I would like to force CMake to use the "Unix Makefiles" generator from within CMakeLists.txt.

This is the command I use now.

cmake -G "Unix Makefiles" .

I would like it to be this.

cmake .

When running on windows with VC installed and a custom tool-chain.

I would expect to be-able to set the generator in the CMakeLists.txt file.

Maybe something like this.

set(CMAKE_GENERATOR "Unix Makefiles")
Ted
  • 14,465
  • 6
  • 28
  • 28

5 Answers5

34

Here is what worked for me - create a file called PreLoad.cmake in your project dir containing this:

set (CMAKE_GENERATOR "Unix Makefiles" CACHE INTERNAL "" FORCE)

Ivan
  • 9,089
  • 4
  • 61
  • 74
  • 4
    It looks like the `Preload.cmake` behavior was not documented in the "official" cmake documentation; see [ticket 17231](https://gitlab.kitware.com/cmake/cmake/issues/17231) -- but good to know! – Michael Kopp Feb 21 '18 at 19:52
  • 3
    Is there a better way as of 2020 / cmake 3.17? This does not seem to work in the same way -GNinja does – Jay Mar 26 '20 at 20:01
18

It seems to me that the variable CMAKE_GENERATOR is set too late if set in the CMakeLists.txt. If you use (even at the beginning of CMakeLists.txt)

set(CMAKE_GENERATOR "Ninja")
message("generator is set to ${CMAKE_GENERATOR}")

you can see in the output something like

% cmake ../source
-- The C compiler identification is GNU 4.9.2
...
-- Detecting CXX compile features - done
generator is set to Ninja
-- Configuring done
-- Generating done
-- Build files have been written to: /tmp/build

So the variable is only set at the very end of the generation procedure. If you use something like

set(CMAKE_GENERATOR "Ninja" CACHE INTERNAL "" FORCE)

in CMakeLists.txt, then in the very first run of cmake ../source (without -G) the default generator is used. The variable CMAKE_GENERATOR is stored in the cache, though. So if you rerun cmake ../source afterwards, it will use the generator as specified in the CMAKE_GENERATOR variable in the cache.

This is surely not the most elegant solution, though ;-) Maybe use a batch file that will actually execute the cmake -G generator for the user...

Michael Kopp
  • 1,571
  • 12
  • 17
  • 2
    I wish they would let the user set all configuration in `CMakeLists.txt`. What's the point if you need a `.bat` over it? – Royi Feb 20 '18 at 15:03
  • 2
    Looks like [Ivan's answer](https://gitlab.kitware.com/cmake/cmake/issues/17231) does something very close to this -- the variable is configured in a cmake config file that is sourced before the actual `CMakeLists.txt` is loaded. – Michael Kopp Feb 21 '18 at 19:56
2

This is not what I get, when I run the same command, cmake will look for a gcc compiler / make utility. If the PATH is not set up correctly it will fail with something like:

D:\Development\build>cmake -G "Unix Makefiles" ..\source
CMake Error: CMake was unable to find a build program corresponding to "Unix Makefiles".  CMAKE_MAKE_PROGRAM is not set.
  You probably need to select a different build tool.
CMake Error: Error required internal CMake variable not set, cmake may be not be built correctly.
Missing variable is:
CMAKE_C_COMPILER_ENV_VAR
CMake Error: Error required internal CMake variable not set, cmake may be not be built correctly.
Missing variable is:
CMAKE_C_COMPILER
CMake Error: Could not find cmake module file:D:/Development/build/CMakeFiles/CMakeCCompiler.cmake
CMake Error: Error required internal CMake variable not set, cmake may be not be built correctly.
Missing variable is:
CMAKE_CXX_COMPILER_ENV_VAR
CMake Error: Error required internal CMake variable not set, cmake may be not be built correctly.
Missing variable is:
CMAKE_CXX_COMPILER
CMake Error: Could not find cmake module file:D:/Development/build/CMakeFiles/CMakeCXXCompiler.cmake
CMake Error: CMAKE_C_COMPILER not set, after EnableLanguage
CMake Error: CMAKE_CXX_COMPILER not set, after EnableLanguage
-- Configuring incomplete, errors occurred!

when gcc / mingw is in the path then everything works fine. So could you provide more information as to your PATH variable or CMAKE version?

Frank
  • 1,122
  • 9
  • 12
  • 1
    Because I am using a custom tool-chain, and I have VC++ installed, I can't rely on CMake selecting a generator. I also don't what to specify one on the command line so that it is easy for the user to clone and build the project. – Ted Jul 02 '12 at 17:07
  • 1
    Ok ... sorry I misunderstood your question. In that case I would recommend placing a CMakeCache.txt into the directory, which is mostly empty but for the CMAKE_GENERATOR variable. Or you could have that cache file in your source repository and pass it along using the -C cmake option. – Frank Jul 12 '12 at 07:46
1

You need to set the generator at the Generate stage so it is written into the cache. You only need to run this command once for the first configuration

cmake .. -DCMAKE_GENERATOR:INTERNAL=Ninja

This will configure Ninja as the default generator.

Later you can simply run

cmake ..

And it would use the Ninja generator as default

You can read more about it under Running CMake from the command line

When running cmake from the command line, it is possible to specify command line options to cmake that will set values in the cache. This is done with a -DVARIABLE:TYPE=VALUE syntax on the command line. This is useful for non-interactive nightly test builds.

Red Shaya
  • 11
  • 1
1

CMake 3.19 introduces a new feature - presets. So, to select proper generator automatically, you can specify it name in CMakePresets.json.

Full description for these files available here: https://cmake.org/cmake/help/latest/manual/cmake-presets.7.html

Alexey Esaulenko
  • 499
  • 2
  • 10