25

When running CMake on one PC, CMake generates NMake files by default. On another, it generates a Visual Studio project.

I know I can override the default by adding -G "NMake Makefiles" to the end of my CMake statement, but I want to know why it defaults to Visual Studio projects on one and NMake files on another.

Chris Finley
  • 3,901
  • 5
  • 24
  • 32

2 Answers2

20

The following is from the CMake Source (version 2.8.4: cmake.cxx: starting line 2039):

  // Try to find the newest VS installed on the computer and
  // use that as a default if -G is not specified
  std::string vsregBase =
    "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\";
  struct VSRegistryEntryName
  {
    const char* MSVersion;
    const char* GeneratorName;
  };
  VSRegistryEntryName version[] = {
    {"6.0", "Visual Studio 6"},
    {"7.0", "Visual Studio 7"},
    {"7.1", "Visual Studio 7 .NET 2003"},
    {"8.0", "Visual Studio 8 2005"},
    {"9.0", "Visual Studio 9 2008"},
    {"10.0", "Visual Studio 10"},
    {0, 0}};
  for(int i =0; version[i].MSVersion != 0; i++)
    {
    std::string reg = vsregBase + version[i].MSVersion;
    reg += ";InstallDir]";
    cmSystemTools::ExpandRegistryValues(reg);
    if (!(reg == "/registry"))
      {
      installedCompiler = version[i].GeneratorName;
      }
    }
  cmGlobalGenerator* gen
    = this->CreateGlobalGenerator(installedCompiler.c_str());
  if(!gen)
    {
    gen = new cmGlobalNMakeMakefileGenerator;
    }
  this->SetGlobalGenerator(gen);
  std::cout << "-- Building for: " << gen->GetName() << "\n";

It appears that CMake looks at the Windows Registry to determine which generator to use. It searches the Visual Studio registry subkeys (6.0, 7.0, etc) in [HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\ for an entry called InstallDir. If one is found, it uses the corresponding generator. (It will use the newest version of Visual Studio available.) Otherwise, it uses the NMake generator.

Note that the InstallDir entry is not always present, even when a particular version of Visual Studio is installed. This may have to do with installation settings or a particular version of Visual Studio (e.g. it seems that the "Express" versions of Visual C++ do not add this entry.)

It is, of course, possible to override the default setting by appending -G {Generator Name} to the end of your CMake command.

Chris Finley
  • 3,901
  • 5
  • 24
  • 32
  • For posterity: there is [an entry in the CMake mailing list](http://www.mail-archive.com/cmake@cmake.org/msg18033.html) that addresses this issue. To change the default generator, it seems you need to either modify the CMake source and recompile or write a small batch file that adds the `-G` option to substitute the generator when none is specified. – André Caron Dec 18 '11 at 00:29
  • 2
    Visual Studio 14 community does not have `InstallDir`. I want to automate 64bit selection of `cmake` generator, and there seems to be no easy way. – dashesy Aug 27 '15 at 00:45
  • 1
    Actually it is there, just should make sure to look inside `W6432Node` if Windows itself is 64bit, because VS is a 32bit application. – dashesy Aug 27 '15 at 01:06
  • 1
    Also [this](https://github.com/Kitware/CMake/blob/master/Source/cmake.cxx#L1422) is the line in the latest cmake for anyone looking. – dashesy Aug 27 '15 at 01:13
  • @dashesy I ran into the same problem. Could you let me know how exactly did you automate 64bit selection for cmake? I tried creating the InstallDir registry and it does nothing – user3667089 Sep 29 '16 at 16:19
  • @user3667089 [This](https://github.com/davisking/dlib/blob/v19.1/setup.py#L177) is the python implementation. It reads the registry in the same way that CMake does. – dashesy Sep 29 '16 at 17:25
  • @dashesy Does that means I have to include the python file in my repo? If my goal is to type cmake .. and it build the 64 bit version automatically instead of needing to type cmake .. -G "Visual Studio 12 Win64", what are the minimal steps I need to take to make this happen? – user3667089 Sep 29 '16 at 17:43
  • 1
    For that you should contact `cmake` project, maybe there is some environment variable that would select the `Win64` version. Alternatively you can use the python version and let that select the 64bit generator. I wish cmake had some option for this. – dashesy Sep 29 '16 at 19:35
  • 1
    The topic was raised within the CMake GitLab issue [here](https://gitlab.kitware.com/cmake/cmake/issues/16339). Alas the issue was closed. – user2023370 Aug 28 '18 at 12:19
  • No that CMake GitLab issue is still open, just no change put forward to address it yet. – Craig Scott Nov 17 '18 at 20:42
3

For posterity.

TLDR: CMake 3.15 and above uses the environment variable CMAKE_GENERATOR as the default generator, it'll be used by cmake if no -G option provided. Or if it was an invalid generator CMake will choose its internal default generator.

CMake has introduced an environment variable CMAKE_GENERATOR controlling the default generator in version 3.15, see this CMake 3.15 Release Notes.

And the document for the environment variable CMAKE_GENERATOR.

Xdminsy
  • 73
  • 1
  • 5