Bladeren bron

VS: Choose VS 2017 instance via environment variable

In the `Visual Studio 15 2017` generator, if the `VS150COMNTOOLS`
environment variable points at a specific VS 2017 instance reported by
the Visual Studio Installer tool, use that as the preferred instance.

Inspired-by: Iyyappa Murugandi <[email protected]>
Fixes: #16846
Brad King 8 jaren geleden
bovenliggende
commit
2644e4c9fc
2 gewijzigde bestanden met toevoegingen van 40 en 0 verwijderingen
  1. 12 0
      Help/generator/Visual Studio 15 2017.rst
  2. 28 0
      Source/cmVSSetupHelper.cxx

+ 12 - 0
Help/generator/Visual Studio 15 2017.rst

@@ -15,6 +15,18 @@ a target platform name optionally at the end of this generator name:
 ``Visual Studio 15 2017 ARM``
   Specify target platform ``ARM``.
 
+Instance Selection
+^^^^^^^^^^^^^^^^^^
+
+VS 2017 supports multiple installations on the same machine.
+CMake queries the Visual Studio Installer to locate VS instances.
+If more than one instance is installed we do not define which one
+is chosen by default.  If the ``VS150COMNTOOLS`` environment variable
+is set and points to the ``Common7/Tools`` directory within one of
+the instances, that instance will be used.  The environment variable
+must remain consistently set whenever CMake is re-run within a given
+build tree.
+
 Toolset Selection
 ^^^^^^^^^^^^^^^^^
 

+ 28 - 0
Source/cmVSSetupHelper.cxx

@@ -1,6 +1,7 @@
 /* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
    file Copyright.txt or https://cmake.org/licensing for details.  */
 #include "cmVSSetupHelper.h"
+#include "cmSystemTools.h"
 
 #ifndef VSSetupConstants
 #define VSSetupConstants
@@ -240,6 +241,22 @@ bool cmVSSetupAPIHelper::EnumerateAndChooseVSInstance()
       setupHelper == NULL)
     return false;
 
+  std::string envVSCommonToolsDir;
+
+  // 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)) {
+    cmSystemTools::ConvertToUnixSlashes(envVSCommonToolsDir);
+  }
+  // FIXME: If the environment variable value changes between runs
+  // of CMake within a given build tree the results are not defined.
+  // Instead we should save a CMAKE_GENERATOR_INSTANCE value in the cache
+  // (similar to CMAKE_GENERATOR_TOOLSET) to hold it persistently.
+  // Unfortunately doing so will require refactoring elsewhere in
+  // order to make sure the value is available in time to create
+  // the generator.
+
   std::vector<VSInstanceInfo> vecVSInstances;
   SmartCOMPtr<IEnumSetupInstances> enumInstances = NULL;
   if (FAILED(
@@ -263,6 +280,17 @@ bool cmVSSetupAPIHelper::EnumerateAndChooseVSInstance()
     instance = instance2 = NULL;
 
     if (isInstalled) {
+      if (!envVSCommonToolsDir.empty()) {
+        std::string currentVSLocation(instanceInfo.VSInstallLocation.begin(),
+                                      instanceInfo.VSInstallLocation.end());
+        cmSystemTools::ConvertToUnixSlashes(currentVSLocation);
+        currentVSLocation += "/Common7/Tools";
+        if (cmSystemTools::ComparePath(currentVSLocation,
+                                       envVSCommonToolsDir)) {
+          chosenInstanceInfo = instanceInfo;
+          return true;
+        }
+      }
       vecVSInstances.push_back(instanceInfo);
     }
   }