Repository: conan-io/conan

Issue:
Improve tools.vcvars_command() with parameters
### vcvarsall syntax
`vcvarsall.bat [architecture] [platform_type] [winsdk_version] [-vcvars_ver=vcversion]`

There are some parameters not being used currently. Improve at least the toolset selection and let the user opt-in.

It could be useful for crossbuilding too as the tool can select host and target architectures.

Info: https://docs.microsoft.com/en-us/cpp/build/building-on-the-command-line

Related to #2929 




Discussion:

Resolving patch:
diff --git a/conans/client/tools/win.py b/conans/client/tools/win.py
--- a/conans/client/tools/win.py
+++ b/conans/client/tools/win.py
@@ -228,7 +228,7 @@ def find_windows_10_sdk():
     return None
 
 
-def vcvars_command(settings, arch=None, compiler_version=None, force=False):
+def vcvars_command(settings, arch=None, compiler_version=None, force=False, vcvars_ver=None, winsdk_version=None):
     arch_setting = arch or settings.get_safe("arch")
     compiler_version = compiler_version or settings.get_safe("compiler.version")
     os_setting = settings.get_safe("os")
@@ -274,6 +274,10 @@ def vcvars_command(settings, arch=None, compiler_version=None, force=False):
                 vcvars_path = os.path.join(vs_path, "VC/Auxiliary/Build/vcvarsall.bat")
                 command = ('set "VSCMD_START_DIR=%%CD%%" && '
                            'call "%s" %s' % (vcvars_path, vcvars_arch))
+                if winsdk_version:
+                    command += " %s" % winsdk_version
+                if vcvars_ver:
+                    command += " -vcvars_ver=%s" % vcvars_ver
             else:
                 vcvars_path = os.path.join(vs_path, "VC/vcvarsall.bat")
                 command = ('call "%s" %s' % (vcvars_path, vcvars_arch))
@@ -294,10 +298,11 @@ def vcvars_command(settings, arch=None, compiler_version=None, force=False):
 
 
 def vcvars_dict(settings, arch=None, compiler_version=None, force=False, filter_known_paths=False,
-                only_diff=True):
+                only_diff=True, vcvars_ver=None, winsdk_version=None):
 
     cmd = vcvars_command(settings, arch=arch,
-                         compiler_version=compiler_version, force=force) + " && echo __BEGINS__ && set"
+                         compiler_version=compiler_version, force=force,
+                         vcvars_ver=vcvars_ver, winsdk_version=winsdk_version) + " && echo __BEGINS__ && set"
     ret = decode_text(subprocess.check_output(cmd, shell=True))
     new_env = {}
     start_reached = False


Test patch:
diff --git a/conans/test/util/tools_test.py b/conans/test/util/tools_test.py
--- a/conans/test/util/tools_test.py
+++ b/conans/test/util/tools_test.py
@@ -670,7 +670,7 @@ def vcvars_dict_test(self):
        
 """.encode("utf-8")
 
-        def vcvars_command_mock(settings, arch, compiler_version, force):  # @UnusedVariable
+        def vcvars_command_mock(settings, arch, compiler_version, force, vcvars_ver, winsdk_version):  # @UnusedVariable
             return "unused command"
 
         def subprocess_check_output_mock(cmd, shell):
diff --git a/conans/test/util/vcvars_arch_test.py b/conans/test/util/vcvars_arch_test.py
--- a/conans/test/util/vcvars_arch_test.py
+++ b/conans/test/util/vcvars_arch_test.py
@@ -71,3 +71,39 @@ def test_arch_override(self):
 
         with self.assertRaises(ConanException):
             tools.vcvars_command(settings, arch='mips')
+
+    def test_vcvars_ver_override(self):
+        if platform.system() != "Windows":
+            return
+        settings = Settings.loads(default_settings_yml)
+        settings.compiler = 'Visual Studio'
+        settings.compiler.version = '15'
+        settings.arch = 'x86_64'
+
+        command = tools.vcvars_command(settings, vcvars_ver='14.14')
+        self.assertIn('vcvarsall.bat', command)
+        self.assertIn('-vcvars_ver=14.14', command)
+
+        settings.compiler.version = '14'
+
+        command = tools.vcvars_command(settings, vcvars_ver='14.14')
+        self.assertIn('vcvarsall.bat', command)
+        self.assertNotIn('-vcvars_ver', command)
+
+    def test_winsdk_version_override(self):
+        if platform.system() != "Windows":
+            return
+        settings = Settings.loads(default_settings_yml)
+        settings.compiler = 'Visual Studio'
+        settings.compiler.version = '15'
+        settings.arch = 'x86_64'
+
+        command = tools.vcvars_command(settings, winsdk_version='8.1')
+        self.assertIn('vcvarsall.bat', command)
+        self.assertIn('8.1', command)
+
+        settings.compiler.version = '14'
+
+        command = tools.vcvars_command(settings, winsdk_version='8.1')
+        self.assertIn('vcvarsall.bat', command)
+        self.assertNotIn('8.1', command)