Ver código fonte

Merge topic 'vs2019'

57e48f16f2 VS: Add Visual Studio 16 2019 generator
bdef729646 VS: Parameterize VS 2017 generator to support future versions
68d316e0cf VS: Rename VS 2017 generator sources to be version-independent
d8ed309d05 VS: Parameterize cmVSSetupAPIHelper instances with VS version

Acked-by: Kitware Robot <[email protected]>
Merge-request: !2789
Brad King 6 anos atrás
pai
commit
41b0c0dc73

+ 49 - 0
Help/generator/Visual Studio 16 2019.rst

@@ -0,0 +1,49 @@
+Visual Studio 16 2019
+---------------------
+
+Generates Visual Studio 16 (VS 2019) project files.
+
+Project Types
+^^^^^^^^^^^^^
+
+Only Visual C++ and C# projects may be generated.  Other types of
+projects (JavaScript, Powershell, Python, etc.) are not supported.
+
+Instance Selection
+^^^^^^^^^^^^^^^^^^
+
+VS 2019 supports multiple installations on the same machine.
+The :variable:`CMAKE_GENERATOR_INSTANCE` variable may be set as a
+cache entry containing the absolute path to a Visual Studio instance.
+If the value is not specified explicitly by the user or a toolchain file,
+CMake queries the Visual Studio Installer to locate VS instances, chooses
+one, and sets the variable as a cache entry to hold the value persistently.
+
+When CMake first chooses an instance, if the ``VS160COMNTOOLS`` environment
+variable is set and points to the ``Common7/Tools`` directory within
+one of the instances, that instance will be used.  Otherwise, if more
+than one instance is installed we do not define which one is chosen
+by default.
+
+Platform Selection
+^^^^^^^^^^^^^^^^^^
+
+The default target platform name (architecture) is that of the host.
+
+The :variable:`CMAKE_GENERATOR_PLATFORM` variable may be set, perhaps
+via the :manual:`cmake(1)` ``-A`` option, to specify a target platform
+name (architecture).  For example:
+
+* ``cmake -G "Visual Studio 16 2019" -A Win32``
+* ``cmake -G "Visual Studio 16 2019" -A x64``
+* ``cmake -G "Visual Studio 16 2019" -A ARM``
+* ``cmake -G "Visual Studio 16 2019" -A ARM64``
+
+Toolset Selection
+^^^^^^^^^^^^^^^^^
+
+The ``v142`` toolset that comes with Visual Studio 16 2019 is selected by
+default.  The :variable:`CMAKE_GENERATOR_TOOLSET` option may be set, perhaps
+via the :manual:`cmake(1)` ``-T`` option, to specify another toolset.
+
+.. include:: VS_TOOLSET_HOST_ARCH.txt

+ 1 - 0
Help/manual/cmake-generators.7.rst

@@ -87,6 +87,7 @@ Visual Studio Generators
    /generator/Visual Studio 12 2013
    /generator/Visual Studio 14 2015
    /generator/Visual Studio 15 2017
+   /generator/Visual Studio 16 2019
 
 Other Generators
 ^^^^^^^^^^^^^^^^

+ 13 - 0
Help/release/dev/vs2019.rst

@@ -0,0 +1,13 @@
+vs2019
+------
+
+* The :generator:`Visual Studio 16 2019` generator was added.  This is
+  experimental and based on "Visual Studio 2019 Preview 1.1" because this
+  version of VS has not been released.
+
+  The VS 2019 generator differs from generators for earlier versions
+  in that it does not provide variants that specify the target platform
+  in the generator name.  Instead :variable:`CMAKE_GENERATOR_PLATFORM`
+  must be used, e.g. through the ``-A`` command-line option.  Furthermore,
+  the default target platform (architecture) is now based on the *host*
+  platform.

+ 1 - 0
Help/variable/MSVC_VERSION.rst

@@ -18,6 +18,7 @@ Known version numbers are::
   1800      = VS 12.0 (v120 toolset)
   1900      = VS 14.0 (v140 toolset)
   1910-1919 = VS 15.0 (v141 toolset)
+  1920-1929 = VS 16.0 (v142 toolset)
 
 See also the  :variable:`CMAKE_<LANG>_COMPILER_VERSION` and
 :variable:`MSVC_TOOLSET_VERSION` variable.

+ 2 - 2
Source/CMakeLists.txt

@@ -696,10 +696,10 @@ if (WIN32)
       cmGlobalVisualStudio12Generator.cxx
       cmGlobalVisualStudio14Generator.h
       cmGlobalVisualStudio14Generator.cxx
-      cmGlobalVisualStudio15Generator.h
-      cmGlobalVisualStudio15Generator.cxx
       cmGlobalVisualStudioGenerator.cxx
       cmGlobalVisualStudioGenerator.h
+      cmGlobalVisualStudioVersionedGenerator.h
+      cmGlobalVisualStudioVersionedGenerator.cxx
       cmIDEFlagTable.h
       cmIDEOptions.cxx
       cmIDEOptions.h

+ 20 - 4
Source/cmCMakeHostSystemInformationCommand.cxx

@@ -10,7 +10,7 @@
 #if defined(_WIN32)
 #  include "cmAlgorithms.h"
 #  include "cmGlobalGenerator.h"
-#  include "cmGlobalVisualStudio15Generator.h"
+#  include "cmGlobalVisualStudioVersionedGenerator.h"
 #  include "cmSystemTools.h"
 #  include "cmVSSetupHelper.h"
 #  define HAVE_VS_SETUP_HELPER
@@ -133,15 +133,31 @@ bool cmCMakeHostSystemInformationCommand::GetValue(
     // If generating for the VS 15 IDE, use the same instance.
     cmGlobalGenerator* gg = this->Makefile->GetGlobalGenerator();
     if (cmHasLiteralPrefix(gg->GetName(), "Visual Studio 15 ")) {
-      cmGlobalVisualStudio15Generator* vs15gen =
-        static_cast<cmGlobalVisualStudio15Generator*>(gg);
+      cmGlobalVisualStudioVersionedGenerator* vs15gen =
+        static_cast<cmGlobalVisualStudioVersionedGenerator*>(gg);
       if (vs15gen->GetVSInstance(value)) {
         return true;
       }
     }
 
     // Otherwise, find a VS 15 instance ourselves.
-    cmVSSetupAPIHelper vsSetupAPIHelper;
+    cmVSSetupAPIHelper vsSetupAPIHelper(15);
+    if (vsSetupAPIHelper.GetVSInstanceInfo(value)) {
+      cmSystemTools::ConvertToUnixSlashes(value);
+    }
+  } else if (key == "VS_16_DIR") {
+    // If generating for the VS 16 IDE, use the same instance.
+    cmGlobalGenerator* gg = this->Makefile->GetGlobalGenerator();
+    if (cmHasLiteralPrefix(gg->GetName(), "Visual Studio 16 ")) {
+      cmGlobalVisualStudioVersionedGenerator* vs16gen =
+        static_cast<cmGlobalVisualStudioVersionedGenerator*>(gg);
+      if (vs16gen->GetVSInstance(value)) {
+        return true;
+      }
+    }
+
+    // Otherwise, find a VS 16 instance ourselves.
+    cmVSSetupAPIHelper vsSetupAPIHelper(16);
     if (vsSetupAPIHelper.GetVSInstanceInfo(value)) {
       cmSystemTools::ConvertToUnixSlashes(value);
     }

+ 2 - 0
Source/cmGlobalVisualStudio10Generator.cxx

@@ -1032,6 +1032,8 @@ const char* cmGlobalVisualStudio10Generator::GetToolsVersion() const
       return "14.0";
     case cmGlobalVisualStudioGenerator::VS15:
       return "15.0";
+    case cmGlobalVisualStudioGenerator::VS16:
+      return "16.0";
   }
   return "";
 }

+ 11 - 0
Source/cmGlobalVisualStudioGenerator.cxx

@@ -86,6 +86,8 @@ const char* cmGlobalVisualStudioGenerator::GetIDEVersion() const
       return "14.0";
     case cmGlobalVisualStudioGenerator::VS15:
       return "15.0";
+    case cmGlobalVisualStudioGenerator::VS16:
+      return "16.0";
   }
   return "";
 }
@@ -139,6 +141,15 @@ void cmGlobalVisualStudioGenerator::WriteSLNHeader(std::ostream& fout)
         fout << "# Visual Studio 15\n";
       }
       break;
+    case cmGlobalVisualStudioGenerator::VS16:
+      // Visual Studio 16 writes .sln format 12.00
+      fout << "Microsoft Visual Studio Solution File, Format Version 12.00\n";
+      if (this->ExpressEdition) {
+        fout << "# Visual Studio Express 16 for Windows Desktop\n";
+      } else {
+        fout << "# Visual Studio 16\n";
+      }
+      break;
   }
 }
 

+ 2 - 1
Source/cmGlobalVisualStudioGenerator.h

@@ -38,7 +38,8 @@ public:
     VS12 = 120,
     /* VS13 = 130 was skipped */
     VS14 = 140,
-    VS15 = 150
+    VS15 = 150,
+    VS16 = 160
   };
 
   virtual ~cmGlobalVisualStudioGenerator();

+ 184 - 31
Source/cmGlobalVisualStudio15Generator.cxx → Source/cmGlobalVisualStudioVersionedGenerator.cxx

@@ -1,6 +1,6 @@
 /* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
    file Copyright.txt or https://cmake.org/licensing for details.  */
-#include "cmGlobalVisualStudio15Generator.h"
+#include "cmGlobalVisualStudioVersionedGenerator.h"
 
 #include "cmAlgorithms.h"
 #include "cmDocumentationEntry.h"
@@ -8,6 +8,61 @@
 #include "cmMakefile.h"
 #include "cmVSSetupHelper.h"
 
+#if defined(_M_ARM64)
+#  define HOST_PLATFORM_NAME "ARM64";
+#elif defined(_M_ARM)
+#  define HOST_PLATFORM_NAME "ARM";
+#elif defined(_M_IA64)
+#  define HOST_PLATFORM_NAME "Itanium";
+#else
+#  include "cmsys/SystemInformation.hxx"
+#endif
+
+static unsigned int VSVersionToMajor(
+  cmGlobalVisualStudioGenerator::VSVersion v)
+{
+  switch (v) {
+    case cmGlobalVisualStudioGenerator::VS9:
+      return 9;
+    case cmGlobalVisualStudioGenerator::VS10:
+      return 10;
+    case cmGlobalVisualStudioGenerator::VS11:
+      return 11;
+    case cmGlobalVisualStudioGenerator::VS12:
+      return 12;
+    case cmGlobalVisualStudioGenerator::VS14:
+      return 14;
+    case cmGlobalVisualStudioGenerator::VS15:
+      return 15;
+    case cmGlobalVisualStudioGenerator::VS16:
+      return 16;
+  }
+  return 0;
+}
+
+static const char* VSVersionToToolset(
+  cmGlobalVisualStudioGenerator::VSVersion v)
+{
+  switch (v) {
+    case cmGlobalVisualStudioGenerator::VS9:
+      return "v90";
+    case cmGlobalVisualStudioGenerator::VS10:
+      return "v100";
+    case cmGlobalVisualStudioGenerator::VS11:
+      return "v110";
+    case cmGlobalVisualStudioGenerator::VS12:
+      return "v120";
+    case cmGlobalVisualStudioGenerator::VS14:
+      return "v140";
+    case cmGlobalVisualStudioGenerator::VS15:
+      return "v141";
+    case cmGlobalVisualStudioGenerator::VS16:
+      // FIXME: VS 2019 Preview 1.1 uses v141 but preview 2 will use v142.
+      return "v141";
+  }
+  return "";
+}
+
 static const char vs15generatorName[] = "Visual Studio 15 2017";
 
 // Map generator name without year to name with year.
@@ -25,7 +80,7 @@ static const char* cmVS15GenName(const std::string& name, std::string& genName)
   return p;
 }
 
-class cmGlobalVisualStudio15Generator::Factory
+class cmGlobalVisualStudioVersionedGenerator::Factory15
   : public cmGlobalGeneratorFactory
 {
 public:
@@ -38,16 +93,19 @@ public:
       return 0;
     }
     if (!*p) {
-      return new cmGlobalVisualStudio15Generator(cm, genName, "");
+      return new cmGlobalVisualStudioVersionedGenerator(
+        cmGlobalVisualStudioGenerator::VS15, cm, genName, "");
     }
     if (*p++ != ' ') {
       return 0;
     }
     if (strcmp(p, "Win64") == 0) {
-      return new cmGlobalVisualStudio15Generator(cm, genName, "x64");
+      return new cmGlobalVisualStudioVersionedGenerator(
+        cmGlobalVisualStudioGenerator::VS15, cm, genName, "x64");
     }
     if (strcmp(p, "ARM") == 0) {
-      return new cmGlobalVisualStudio15Generator(cm, genName, "ARM");
+      return new cmGlobalVisualStudioVersionedGenerator(
+        cmGlobalVisualStudioGenerator::VS15, cm, genName, "ARM");
     }
     return 0;
   }
@@ -70,35 +128,122 @@ public:
   bool SupportsPlatform() const override { return true; }
 };
 
-cmGlobalGeneratorFactory* cmGlobalVisualStudio15Generator::NewFactory()
+cmGlobalGeneratorFactory*
+cmGlobalVisualStudioVersionedGenerator::NewFactory15()
+{
+  return new Factory15;
+}
+
+static const char vs16generatorName[] = "Visual Studio 16 2019";
+
+// Map generator name without year to name with year.
+static const char* cmVS16GenName(const std::string& name, std::string& genName)
+{
+  if (strncmp(name.c_str(), vs16generatorName,
+              sizeof(vs16generatorName) - 6) != 0) {
+    return 0;
+  }
+  const char* p = name.c_str() + sizeof(vs16generatorName) - 6;
+  if (cmHasLiteralPrefix(p, " 2019")) {
+    p += 5;
+  }
+  genName = std::string(vs16generatorName) + p;
+  return p;
+}
+
+class cmGlobalVisualStudioVersionedGenerator::Factory16
+  : public cmGlobalGeneratorFactory
+{
+public:
+  virtual cmGlobalGenerator* CreateGlobalGenerator(const std::string& name,
+                                                   cmake* cm) const
+  {
+    std::string genName;
+    const char* p = cmVS16GenName(name, genName);
+    if (!p) {
+      return 0;
+    }
+    if (!*p) {
+      return new cmGlobalVisualStudioVersionedGenerator(
+        cmGlobalVisualStudioGenerator::VS16, cm, genName, "");
+    }
+    return 0;
+  }
+
+  virtual void GetDocumentation(cmDocumentationEntry& entry) const
+  {
+    entry.Name = std::string(vs16generatorName);
+    entry.Brief = "Generates Visual Studio 2019 project files.  "
+                  "Use -A option to specify architecture.";
+  }
+
+  virtual void GetGenerators(std::vector<std::string>& names) const
+  {
+    names.push_back(vs16generatorName);
+  }
+
+  bool SupportsToolset() const override { return true; }
+  bool SupportsPlatform() const override { return true; }
+};
+
+cmGlobalGeneratorFactory*
+cmGlobalVisualStudioVersionedGenerator::NewFactory16()
 {
-  return new Factory;
+  return new Factory16;
 }
 
-cmGlobalVisualStudio15Generator::cmGlobalVisualStudio15Generator(
-  cmake* cm, const std::string& name,
+cmGlobalVisualStudioVersionedGenerator::cmGlobalVisualStudioVersionedGenerator(
+  VSVersion version, cmake* cm, const std::string& name,
   std::string const& platformInGeneratorName)
   : cmGlobalVisualStudio14Generator(cm, name, platformInGeneratorName)
+  , vsSetupAPIHelper(VSVersionToMajor(version))
 {
+  this->Version = version;
   this->ExpressEdition = false;
-  this->DefaultPlatformToolset = "v141";
-  this->DefaultCLFlagTableName = "v141";
-  this->DefaultCSharpFlagTableName = "v141";
-  this->DefaultLinkFlagTableName = "v141";
-  this->Version = VS15;
+  this->DefaultPlatformToolset = VSVersionToToolset(this->Version);
+  this->DefaultCLFlagTableName = VSVersionToToolset(this->Version);
+  this->DefaultCSharpFlagTableName = VSVersionToToolset(this->Version);
+  this->DefaultLinkFlagTableName = VSVersionToToolset(this->Version);
+  if (this->Version >= cmGlobalVisualStudioGenerator::VS16) {
+#ifdef HOST_PLATFORM_NAME
+    this->DefaultPlatformName = HOST_PLATFORM_NAME;
+#else
+    cmsys::SystemInformation info;
+    if (info.Is64Bits()) {
+      this->DefaultPlatformName = "x64";
+    } else {
+      this->DefaultPlatformName = "Win32";
+    }
+#endif
+  }
 }
 
-bool cmGlobalVisualStudio15Generator::MatchesGeneratorName(
+bool cmGlobalVisualStudioVersionedGenerator::MatchesGeneratorName(
   const std::string& name) const
 {
   std::string genName;
-  if (cmVS15GenName(name, genName)) {
-    return genName == this->GetName();
+  switch (this->Version) {
+    case cmGlobalVisualStudioGenerator::VS9:
+    case cmGlobalVisualStudioGenerator::VS10:
+    case cmGlobalVisualStudioGenerator::VS11:
+    case cmGlobalVisualStudioGenerator::VS12:
+    case cmGlobalVisualStudioGenerator::VS14:
+      break;
+    case cmGlobalVisualStudioGenerator::VS15:
+      if (cmVS15GenName(name, genName)) {
+        return genName == this->GetName();
+      }
+      break;
+    case cmGlobalVisualStudioGenerator::VS16:
+      if (cmVS16GenName(name, genName)) {
+        return genName == this->GetName();
+      }
+      break;
   }
   return false;
 }
 
-bool cmGlobalVisualStudio15Generator::SetGeneratorInstance(
+bool cmGlobalVisualStudioVersionedGenerator::SetGeneratorInstance(
   std::string const& i, cmMakefile* mf)
 {
   if (!i.empty()) {
@@ -140,12 +285,13 @@ bool cmGlobalVisualStudio15Generator::SetGeneratorInstance(
   return true;
 }
 
-bool cmGlobalVisualStudio15Generator::GetVSInstance(std::string& dir) const
+bool cmGlobalVisualStudioVersionedGenerator::GetVSInstance(
+  std::string& dir) const
 {
   return vsSetupAPIHelper.GetVSInstanceInfo(dir);
 }
 
-bool cmGlobalVisualStudio15Generator::IsDefaultToolset(
+bool cmGlobalVisualStudioVersionedGenerator::IsDefaultToolset(
   const std::string& version) const
 {
   if (version.empty()) {
@@ -166,7 +312,7 @@ bool cmGlobalVisualStudio15Generator::IsDefaultToolset(
   return false;
 }
 
-std::string cmGlobalVisualStudio15Generator::GetAuxiliaryToolset() const
+std::string cmGlobalVisualStudioVersionedGenerator::GetAuxiliaryToolset() const
 {
   const char* version = this->GetPlatformToolsetVersion();
   if (version) {
@@ -185,7 +331,7 @@ std::string cmGlobalVisualStudio15Generator::GetAuxiliaryToolset() const
   return {};
 }
 
-bool cmGlobalVisualStudio15Generator::InitializeWindows(cmMakefile* mf)
+bool cmGlobalVisualStudioVersionedGenerator::InitializeWindows(cmMakefile* mf)
 {
   // If the Win 8.1 SDK is installed then we can select a SDK matching
   // the target Windows version.
@@ -197,13 +343,13 @@ bool cmGlobalVisualStudio15Generator::InitializeWindows(cmMakefile* mf)
   return this->SelectWindows10SDK(mf, false);
 }
 
-bool cmGlobalVisualStudio15Generator::SelectWindowsStoreToolset(
+bool cmGlobalVisualStudioVersionedGenerator::SelectWindowsStoreToolset(
   std::string& toolset) const
 {
   if (cmHasLiteralPrefix(this->SystemVersion, "10.0")) {
     if (this->IsWindowsStoreToolsetInstalled() &&
         this->IsWindowsDesktopToolsetInstalled()) {
-      toolset = "v141"; // VS 15 uses v141 toolset
+      toolset = VSVersionToToolset(this->Version);
       return true;
     } else {
       return false;
@@ -213,17 +359,19 @@ bool cmGlobalVisualStudio15Generator::SelectWindowsStoreToolset(
     toolset);
 }
 
-bool cmGlobalVisualStudio15Generator::IsWindowsDesktopToolsetInstalled() const
+bool cmGlobalVisualStudioVersionedGenerator::IsWindowsDesktopToolsetInstalled()
+  const
 {
-  return vsSetupAPIHelper.IsVS2017Installed();
+  return vsSetupAPIHelper.IsVSInstalled();
 }
 
-bool cmGlobalVisualStudio15Generator::IsWindowsStoreToolsetInstalled() const
+bool cmGlobalVisualStudioVersionedGenerator::IsWindowsStoreToolsetInstalled()
+  const
 {
   return vsSetupAPIHelper.IsWin10SDKInstalled();
 }
 
-bool cmGlobalVisualStudio15Generator::IsWin81SDKInstalled() const
+bool cmGlobalVisualStudioVersionedGenerator::IsWin81SDKInstalled() const
 {
   // Does the VS installer tool know about one?
   if (vsSetupAPIHelper.IsWin81SDKInstalled()) {
@@ -245,18 +393,23 @@ bool cmGlobalVisualStudio15Generator::IsWin81SDKInstalled() const
   return false;
 }
 
-std::string cmGlobalVisualStudio15Generator::GetWindows10SDKMaxVersion() const
+std::string cmGlobalVisualStudioVersionedGenerator::GetWindows10SDKMaxVersion()
+  const
 {
   return std::string();
 }
 
-std::string cmGlobalVisualStudio15Generator::FindMSBuildCommand()
+std::string cmGlobalVisualStudioVersionedGenerator::FindMSBuildCommand()
 {
   std::string msbuild;
 
   // Ask Visual Studio Installer tool.
   std::string vs;
   if (vsSetupAPIHelper.GetVSInstanceInfo(vs)) {
+    msbuild = vs + "/MSBuild/Current/Bin/MSBuild.exe";
+    if (cmSystemTools::FileExists(msbuild)) {
+      return msbuild;
+    }
     msbuild = vs + "/MSBuild/15.0/Bin/MSBuild.exe";
     if (cmSystemTools::FileExists(msbuild)) {
       return msbuild;
@@ -267,7 +420,7 @@ std::string cmGlobalVisualStudio15Generator::FindMSBuildCommand()
   return msbuild;
 }
 
-std::string cmGlobalVisualStudio15Generator::FindDevEnvCommand()
+std::string cmGlobalVisualStudioVersionedGenerator::FindDevEnvCommand()
 {
   std::string devenv;
 

+ 14 - 9
Source/cmGlobalVisualStudio15Generator.h → Source/cmGlobalVisualStudioVersionedGenerator.h

@@ -1,7 +1,7 @@
 /* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
    file Copyright.txt or https://cmake.org/licensing for details.  */
-#ifndef cmGlobalVisualStudio15Generator_h
-#define cmGlobalVisualStudio15Generator_h
+#ifndef cmGlobalVisualStudioVersionedGenerator_h
+#define cmGlobalVisualStudioVersionedGenerator_h
 
 #include "cmConfigure.h" // IWYU pragma: keep
 
@@ -14,11 +14,13 @@
 class cmGlobalGeneratorFactory;
 class cmake;
 
-/** \class cmGlobalVisualStudio15Generator  */
-class cmGlobalVisualStudio15Generator : public cmGlobalVisualStudio14Generator
+/** \class cmGlobalVisualStudioVersionedGenerator  */
+class cmGlobalVisualStudioVersionedGenerator
+  : public cmGlobalVisualStudio14Generator
 {
 public:
-  static cmGlobalGeneratorFactory* NewFactory();
+  static cmGlobalGeneratorFactory* NewFactory15();
+  static cmGlobalGeneratorFactory* NewFactory16();
 
   bool MatchesGeneratorName(const std::string& name) const override;
 
@@ -30,8 +32,9 @@ public:
   std::string GetAuxiliaryToolset() const override;
 
 protected:
-  cmGlobalVisualStudio15Generator(cmake* cm, const std::string& name,
-                                  std::string const& platformInGeneratorName);
+  cmGlobalVisualStudioVersionedGenerator(
+    VSVersion version, cmake* cm, const std::string& name,
+    std::string const& platformInGeneratorName);
 
   bool InitializeWindows(cmMakefile* mf) override;
   bool SelectWindowsStoreToolset(std::string& toolset) const override;
@@ -53,8 +56,10 @@ protected:
   std::string FindDevEnvCommand() override;
 
 private:
-  class Factory;
-  friend class Factory;
+  class Factory15;
+  friend class Factory15;
+  class Factory16;
+  friend class Factory16;
   mutable cmVSSetupAPIHelper vsSetupAPIHelper;
 };
 #endif

+ 9 - 9
Source/cmVSSetupHelper.cxx

@@ -57,8 +57,9 @@ std::string VSInstanceInfo::GetInstallLocation() const
   return loc;
 }
 
-cmVSSetupAPIHelper::cmVSSetupAPIHelper()
-  : setupConfig(NULL)
+cmVSSetupAPIHelper::cmVSSetupAPIHelper(unsigned int version)
+  : Version(version)
+  , setupConfig(NULL)
   , setupConfig2(NULL)
   , setupHelper(NULL)
   , initializationFailure(false)
@@ -88,7 +89,7 @@ bool cmVSSetupAPIHelper::SetVSInstance(std::string const& vsInstallLocation)
   return this->EnumerateAndChooseVSInstance();
 }
 
-bool cmVSSetupAPIHelper::IsVS2017Installed()
+bool cmVSSetupAPIHelper::IsVSInstalled()
 {
   return this->EnumerateAndChooseVSInstance();
 }
@@ -312,11 +313,11 @@ bool cmVSSetupAPIHelper::EnumerateAndChooseVSInstance()
     return false;
 
   std::string envVSCommonToolsDir;
+  std::string envVSCommonToolsDirEnvName =
+    "VS" + std::to_string(this->Version) + "0COMNTOOLS";
 
-  // FIXME: When we support VS versions beyond 2017, the version
-  // to choose will be passed in by the caller.  We need to map that
-  // to a per-version name of this environment variable.
-  if (cmSystemTools::GetEnv("VS150COMNTOOLS", envVSCommonToolsDir)) {
+  if (cmSystemTools::GetEnv(envVSCommonToolsDirEnvName.c_str(),
+                            envVSCommonToolsDir)) {
     cmSystemTools::ConvertToUnixSlashes(envVSCommonToolsDir);
   }
 
@@ -328,8 +329,7 @@ bool cmVSSetupAPIHelper::EnumerateAndChooseVSInstance()
     return false;
   }
 
-  // FIXME: Add a way for caller to specify other versions.
-  std::wstring wantVersion = std::to_wstring(15) + L'.';
+  std::wstring const wantVersion = std::to_wstring(this->Version) + L'.';
 
   SmartCOMPtr<ISetupInstance> instance;
   while (SUCCEEDED(enumInstances->Next(1, &instance, NULL)) && instance) {

+ 4 - 2
Source/cmVSSetupHelper.h

@@ -120,12 +120,12 @@ struct VSInstanceInfo
 class cmVSSetupAPIHelper
 {
 public:
-  cmVSSetupAPIHelper();
+  cmVSSetupAPIHelper(unsigned int version);
   ~cmVSSetupAPIHelper();
 
   bool SetVSInstance(std::string const& vsInstallLocation);
 
-  bool IsVS2017Installed();
+  bool IsVSInstalled();
   bool GetVSInstanceInfo(std::string& vsInstallLocation);
   bool GetVCToolsetVersion(std::string& vsToolsetVersion);
   bool IsWin10SDKInstalled();
@@ -140,6 +140,8 @@ private:
   int ChooseVSInstance(const std::vector<VSInstanceInfo>& vecVSInstances);
   bool EnumerateAndChooseVSInstance();
 
+  unsigned int Version;
+
   // COM ptrs to query about VS instances
   SmartCOMPtr<ISetupConfiguration> setupConfig;
   SmartCOMPtr<ISetupConfiguration2> setupConfig2;

+ 1 - 0
Source/cmVisualStudioGeneratorOptions.cxx

@@ -70,6 +70,7 @@ void cmVisualStudioGeneratorOptions::FixExceptionHandlingDefault()
     case cmGlobalVisualStudioGenerator::VS12:
     case cmGlobalVisualStudioGenerator::VS14:
     case cmGlobalVisualStudioGenerator::VS15:
+    case cmGlobalVisualStudioGenerator::VS16:
       // by default VS puts <ExceptionHandling></ExceptionHandling> empty
       // for a project, to make our projects look the same put a new line
       // and space over for the closing </ExceptionHandling> as the default

+ 8 - 4
Source/cmake.cxx

@@ -55,8 +55,8 @@
 #    include "cmGlobalVisualStudio11Generator.h"
 #    include "cmGlobalVisualStudio12Generator.h"
 #    include "cmGlobalVisualStudio14Generator.h"
-#    include "cmGlobalVisualStudio15Generator.h"
 #    include "cmGlobalVisualStudio9Generator.h"
+#    include "cmGlobalVisualStudioVersionedGenerator.h"
 #    include "cmVSSetupHelper.h"
 
 #    define CMAKE_HAVE_VS_GENERATORS
@@ -1545,8 +1545,9 @@ void cmake::CreateDefaultGlobalGenerator()
     "\\Setup\\VC;ProductDir", //
     ";InstallDir"             //
   };
-  cmVSSetupAPIHelper vsSetupAPIHelper;
-  if (vsSetupAPIHelper.IsVS2017Installed()) {
+  if (cmVSSetupAPIHelper(16).IsVSInstalled()) {
+    found = "Visual Studio 16 2019";
+  } else if (cmVSSetupAPIHelper(15).IsVSInstalled()) {
     found = "Visual Studio 15 2017";
   } else {
     for (VSVersionedGenerator const* g = cm::cbegin(vsGenerators);
@@ -1800,7 +1801,10 @@ void cmake::AddDefaultGenerators()
 {
 #if defined(_WIN32) && !defined(__CYGWIN__)
 #  if !defined(CMAKE_BOOT_MINGW)
-  this->Generators.push_back(cmGlobalVisualStudio15Generator::NewFactory());
+  this->Generators.push_back(
+    cmGlobalVisualStudioVersionedGenerator::NewFactory16());
+  this->Generators.push_back(
+    cmGlobalVisualStudioVersionedGenerator::NewFactory15());
   this->Generators.push_back(cmGlobalVisualStudio14Generator::NewFactory());
   this->Generators.push_back(cmGlobalVisualStudio12Generator::NewFactory());
   this->Generators.push_back(cmGlobalVisualStudio11Generator::NewFactory());

+ 1 - 1
Tests/RunCMake/CMakeLists.txt

@@ -335,7 +335,7 @@ if (GTK2_FOUND)
 endif()
 
 if("${CMAKE_GENERATOR}" MATCHES "Visual Studio")
-  add_RunCMake_test(include_external_msproject)
+  add_RunCMake_test(include_external_msproject -DVS_PLATFORM_NAME=${CMAKE_VS_PLATFORM_NAME})
   if("${CMAKE_GENERATOR}" MATCHES "Visual Studio (9|10)" AND NOT CMAKE_VS_DEVENV_COMMAND)
     set(NO_USE_FOLDERS 1)
   endif()

+ 2 - 2
Tests/RunCMake/GeneratorPlatform/RunCMakeTest.cmake

@@ -3,7 +3,7 @@ include(RunCMake)
 set(RunCMake_GENERATOR_PLATFORM "")
 run_cmake(NoPlatform)
 
-if("${RunCMake_GENERATOR}" MATCHES "^Visual Studio ([89]|1[01245])( 20[0-9][0-9])?$")
+if("${RunCMake_GENERATOR}" MATCHES "^Visual Studio ([89]|1[012456])( 20[0-9][0-9])?$")
   set(RunCMake_GENERATOR_PLATFORM "x64")
   run_cmake(x64Platform)
 else()
@@ -17,7 +17,7 @@ set(RunCMake_TEST_OPTIONS -A "Extra Platform")
 run_cmake(TwoPlatforms)
 unset(RunCMake_TEST_OPTIONS)
 
-if("${RunCMake_GENERATOR}" MATCHES "^Visual Studio ([89]|1[01245])( 20[0-9][0-9])?$")
+if("${RunCMake_GENERATOR}" MATCHES "^Visual Studio ([89]|1[012456])( 20[0-9][0-9])?$")
   set(RunCMake_TEST_OPTIONS -DCMAKE_TOOLCHAIN_FILE=${RunCMake_SOURCE_DIR}/TestPlatform-toolchain.cmake)
   run_cmake(TestPlatformToolchain)
   unset(RunCMake_TEST_OPTIONS)

+ 4 - 4
Tests/RunCMake/GeneratorToolset/RunCMakeTest.cmake

@@ -3,7 +3,7 @@ include(RunCMake)
 set(RunCMake_GENERATOR_TOOLSET "")
 run_cmake(NoToolset)
 
-if("${RunCMake_GENERATOR}" MATCHES "Visual Studio 1[01245]")
+if("${RunCMake_GENERATOR}" MATCHES "Visual Studio 1[012456]")
   set(RunCMake_GENERATOR_TOOLSET "Test Toolset")
   run_cmake(TestToolset)
   set(RunCMake_GENERATOR_TOOLSET "Test Toolset,cuda=Test Cuda")
@@ -12,7 +12,7 @@ if("${RunCMake_GENERATOR}" MATCHES "Visual Studio 1[01245]")
   run_cmake(TestToolsetCudaOnly)
   set(RunCMake_GENERATOR_TOOLSET "cuda=Test Cuda")
   run_cmake(TestToolsetCudaOnly)
-  if("${RunCMake_GENERATOR}" MATCHES "Visual Studio 1[245]")
+  if("${RunCMake_GENERATOR}" MATCHES "Visual Studio 1[2456]")
     set(RunCMake_GENERATOR_TOOLSET "Test Toolset,host=x64")
     run_cmake(TestToolsetHostArchBoth)
     set(RunCMake_GENERATOR_TOOLSET ",host=x64")
@@ -25,7 +25,7 @@ if("${RunCMake_GENERATOR}" MATCHES "Visual Studio 1[01245]")
     run_cmake(BadToolsetHostArch)
     set(RunCMake_GENERATOR_TOOLSET "Test Toolset,host=x64,host=x64")
     run_cmake(BadToolsetHostArchTwice)
-    if("${RunCMake_GENERATOR}" MATCHES "Visual Studio 15")
+    if("${RunCMake_GENERATOR}" MATCHES "Visual Studio 1[56]")
       set(RunCMake_GENERATOR_TOOLSET "Test Toolset,version=Test Toolset Version")
       run_cmake(TestToolsetVersionBoth)
       set(RunCMake_GENERATOR_TOOLSET ",version=Test Toolset Version")
@@ -59,7 +59,7 @@ set(RunCMake_TEST_OPTIONS -T "Extra Toolset")
 run_cmake(TwoToolsets)
 unset(RunCMake_TEST_OPTIONS)
 
-if("${RunCMake_GENERATOR}" MATCHES "Visual Studio 1[01245]|Xcode")
+if("${RunCMake_GENERATOR}" MATCHES "Visual Studio 1[012456]|Xcode")
   set(RunCMake_TEST_OPTIONS -DCMAKE_TOOLCHAIN_FILE=${RunCMake_SOURCE_DIR}/TestToolset-toolchain.cmake)
   run_cmake(TestToolsetToolchain)
   unset(RunCMake_TEST_OPTIONS)

+ 2 - 0
Tests/RunCMake/include_external_msproject/check_utils.cmake

@@ -100,6 +100,8 @@ function(check_project test name guid type platform imported_release_config_name
       set(platform "${RunCMake_GENERATOR_PLATFORM}")
     elseif("${RunCMake_GENERATOR}" MATCHES "Win64")
       set(platform "x64")
+    elseif(VS_PLATFORM_NAME)
+      set(platform "${VS_PLATFORM_NAME}")
     else()
       set(platform "Win32")
     endif()

+ 2 - 2
Tests/VSExternalInclude/CMakeLists.txt

@@ -1,7 +1,7 @@
 cmake_minimum_required (VERSION 2.6)
 project(VSExternalInclude)
 
-if(${CMAKE_GENERATOR} MATCHES "Visual Studio 1[01245]")
+if(${CMAKE_GENERATOR} MATCHES "Visual Studio 1[012456]")
   set(PROJECT_EXT vcxproj)
 else()
   set(PROJECT_EXT vcproj)
@@ -55,7 +55,7 @@ add_dependencies(VSExternalInclude lib2)
 # and the sln file can no longer be the only source
 # of that depend.  So, for VS 10 make the executable
 # depend on lib1 and lib2
-if(${CMAKE_GENERATOR} MATCHES "Visual Studio 1[01245]")
+if(${CMAKE_GENERATOR} MATCHES "Visual Studio 1[012456]")
   add_dependencies(VSExternalInclude lib1)
 endif()