浏览代码

Merge topic 'vs-default-generator'

5380948f cmake: Fix default VS generator selection for Microsoft Build Tools
1aee54ed cmake: Simplify default generator search by switching direction
24c86e1c cmake: Use array iteration for default generator VS variants
6db64ad4 cmake: Use array iteration for default generator list
d3df00ae cmake: Rename default generator selection list variable
10160f69 cmake: Rename default generator selection internal variable
0838d20e cmake: Simplify VS registry entry lookup
8f33de92 cmake: Factor out default generator selection into helper
Brad King 9 年之前
父节点
当前提交
1b592b6458
共有 2 个文件被更改,包括 60 次插入48 次删除
  1. 58 48
      Source/cmake.cxx
  2. 2 0
      Source/cmake.h

+ 58 - 48
Source/cmake.cxx

@@ -1313,54 +1313,7 @@ int cmake::ActualConfigure()
       cmSystemTools::SetForceUnixPaths(
         this->GlobalGenerator->GetForceUnixPaths());
     } else {
-#if defined(_WIN32) && !defined(__CYGWIN__) && !defined(CMAKE_BOOT_MINGW)
-      std::string installedCompiler;
-      // Try to find the newest VS installed on the computer and
-      // use that as a default if -G is not specified
-      const std::string vsregBase =
-        "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\";
-      std::vector<std::string> vsVerions;
-      vsVerions.push_back("VisualStudio\\");
-      vsVerions.push_back("VCExpress\\");
-      vsVerions.push_back("WDExpress\\");
-      struct VSRegistryEntryName
-      {
-        const char* MSVersion;
-        const char* GeneratorName;
-      };
-      VSRegistryEntryName version[] = {
-        /* clang-format needs this comment to break after the opening brace */
-        { "7.1", "Visual Studio 7 .NET 2003" },
-        { "8.0", "Visual Studio 8 2005" },
-        { "9.0", "Visual Studio 9 2008" },
-        { "10.0", "Visual Studio 10 2010" },
-        { "11.0", "Visual Studio 11 2012" },
-        { "12.0", "Visual Studio 12 2013" },
-        { "14.0", "Visual Studio 14 2015" },
-        { "15.0", "Visual Studio 15" },
-        { 0, 0 }
-      };
-      for (int i = 0; version[i].MSVersion != 0; i++) {
-        for (size_t b = 0; b < vsVerions.size(); b++) {
-          std::string reg = vsregBase + vsVerions[b] + version[i].MSVersion;
-          reg += ";InstallDir]";
-          cmSystemTools::ExpandRegistryValues(reg, cmSystemTools::KeyWOW64_32);
-          if (!(reg == "/registry")) {
-            installedCompiler = version[i].GeneratorName;
-            break;
-          }
-        }
-      }
-      cmGlobalGenerator* gen =
-        this->CreateGlobalGenerator(installedCompiler.c_str());
-      if (!gen) {
-        gen = new cmGlobalNMakeMakefileGenerator(this);
-      }
-      this->SetGlobalGenerator(gen);
-      std::cout << "-- Building for: " << gen->GetName() << "\n";
-#else
-      this->SetGlobalGenerator(new cmGlobalUnixMakefileGenerator3(this));
-#endif
+      this->CreateDefaultGlobalGenerator();
     }
     if (!this->GlobalGenerator) {
       cmSystemTools::Error("Could not create generator");
@@ -1488,6 +1441,63 @@ int cmake::ActualConfigure()
   return 0;
 }
 
+void cmake::CreateDefaultGlobalGenerator()
+{
+#if defined(_WIN32) && !defined(__CYGWIN__) && !defined(CMAKE_BOOT_MINGW)
+  std::string found;
+  // Try to find the newest VS installed on the computer and
+  // use that as a default if -G is not specified
+  const std::string vsregBase = "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\";
+  static const char* const vsVariants[] = {
+    /* clang-format needs this comment to break after the opening brace */
+    "VisualStudio\\", "VCExpress\\", "WDExpress\\"
+  };
+  struct VSVersionedGenerator
+  {
+    const char* MSVersion;
+    const char* GeneratorName;
+  };
+  static VSVersionedGenerator const vsGenerators[] = {
+    { "15.0", "Visual Studio 15" },      //
+    { "14.0", "Visual Studio 14 2015" }, //
+    { "12.0", "Visual Studio 12 2013" }, //
+    { "11.0", "Visual Studio 11 2012" }, //
+    { "10.0", "Visual Studio 10 2010" }, //
+    { "9.0", "Visual Studio 9 2008" },   //
+    { "8.0", "Visual Studio 8 2005" },   //
+    { "7.1", "Visual Studio 7 .NET 2003" }
+  };
+  static const char* const vsEntries[] = {
+    "\\Setup\\VC;ProductDir", //
+    ";InstallDir"             //
+  };
+  for (VSVersionedGenerator const* g = cmArrayBegin(vsGenerators);
+       found.empty() && g != cmArrayEnd(vsGenerators); ++g) {
+    for (const char* const* v = cmArrayBegin(vsVariants);
+         found.empty() && v != cmArrayEnd(vsVariants); ++v) {
+      for (const char* const* e = cmArrayBegin(vsEntries);
+           found.empty() && e != cmArrayEnd(vsEntries); ++e) {
+        std::string const reg = vsregBase + *v + g->MSVersion + *e;
+        std::string dir;
+        if (cmSystemTools::ReadRegistryValue(reg, dir,
+                                             cmSystemTools::KeyWOW64_32) &&
+            cmSystemTools::PathExists(dir)) {
+          found = g->GeneratorName;
+        }
+      }
+    }
+  }
+  cmGlobalGenerator* gen = this->CreateGlobalGenerator(found);
+  if (!gen) {
+    gen = new cmGlobalNMakeMakefileGenerator(this);
+  }
+  this->SetGlobalGenerator(gen);
+  std::cout << "-- Building for: " << gen->GetName() << "\n";
+#else
+  this->SetGlobalGenerator(new cmGlobalUnixMakefileGenerator3(this));
+#endif
+}
+
 void cmake::PreLoadCMakeFiles()
 {
   std::vector<std::string> args;

+ 2 - 0
Source/cmake.h

@@ -500,6 +500,8 @@ private:
   // Print a list of valid generators to stderr.
   void PrintGeneratorList();
 
+  void CreateDefaultGlobalGenerator();
+
   /**
    * Convert a message type between a warning and an error, based on the state
    * of the error output CMake variables, in the cache.