diff --git a/conan/tools/microsoft/visual.py b/conan/tools/microsoft/visual.py index dd806c5fe40..a154d31de7f 100644 --- a/conan/tools/microsoft/visual.py +++ b/conan/tools/microsoft/visual.py @@ -133,7 +133,13 @@ def generate(self, scope="build"): "v143": "14.3"}.get(toolset_version) else: vs_version = vs_ide_version(conanfile) - vcvars_ver = _vcvars_vers(conanfile, compiler, vs_version) + if int(vs_version) <= 14: + vcvars_ver = None + else: + compiler_version = str(conanfile.settings.compiler.version) + compiler_update = conanfile.settings.get_safe("compiler.update", "") + # The equivalent of compiler 19.26 is toolset 14.26 + vcvars_ver = "14.{}{}".format(compiler_version[-1], compiler_update) vcvarsarch = _vcvars_arch(conanfile) winsdk_version = conanfile.conf.get("tools.microsoft:winsdk_version", check_type=str) @@ -177,7 +183,6 @@ def generate(self, scope="build"): _create_deactivate_vcvars_file(conanfile, conan_vcvars_ps1) - def _create_deactivate_vcvars_file(conanfile, filename): deactivate_filename = f"deactivate_{filename}" message = f"[{deactivate_filename}]: vcvars env cannot be deactivated" @@ -189,6 +194,7 @@ def _create_deactivate_vcvars_file(conanfile, filename): path = os.path.join(conanfile.generators_folder, deactivate_filename) save(path, content) + def vs_ide_version(conanfile): """ Gets the VS IDE version as string. It'll use the ``compiler.version`` (if exists) and/or the @@ -298,7 +304,7 @@ def _vcvars_arch(conanfile): 'x86_64': 'amd64', 'armv7': 'amd64_arm', 'armv8': 'amd64_arm64', - 'arm64ec':'amd64_arm64'}.get(arch_host) + 'arm64ec': 'amd64_arm64'}.get(arch_host) elif arch_build == 'x86': arch = {'x86': 'x86', 'x86_64': 'x86_amd64', @@ -316,18 +322,6 @@ def _vcvars_arch(conanfile): return arch -def _vcvars_vers(conanfile, compiler, vs_version): - if int(vs_version) <= 14: - return None - - assert compiler == "msvc" - # Code similar to CMakeToolchain toolset one - compiler_version = str(conanfile.settings.compiler.version) - # The equivalent of compiler 192 is toolset 14.2 - vcvars_ver = "14.{}".format(compiler_version[-1]) - return vcvars_ver - - def is_msvc(conanfile, build_context=False): """ Validates if the current compiler is ``msvc``. diff --git a/conans/test/integration/toolchains/microsoft/vcvars_test.py b/conans/test/integration/toolchains/microsoft/vcvars_test.py index 2e5460a75de..dfee025d937 100644 --- a/conans/test/integration/toolchains/microsoft/vcvars_test.py +++ b/conans/test/integration/toolchains/microsoft/vcvars_test.py @@ -51,6 +51,7 @@ def test_vcvars_generator_skip(): client.run('install . -pr=profile') assert not os.path.exists(os.path.join(client.current_folder, "conanvcvars.bat")) + @pytest.mark.skipif(platform.system() not in ["Linux"], reason="Requires Linux") def test_vcvars_generator_skip_on_linux(): """ @@ -65,6 +66,7 @@ def test_vcvars_generator_skip_on_linux(): '-s compiler.runtime=dynamic') assert not os.path.exists(os.path.join(client.current_folder, "conanvcvars.bat")) + @pytest.mark.skipif(platform.system() not in ["Windows"], reason="Requires Windows") def test_vcvars_generator_string(): client = TestClient(path_with_spaces=False) @@ -140,6 +142,26 @@ class TestConan(ConanFile): vcvars = client.load("conanvcvars.bat") assert 'vcvarsall.bat" amd64 8.1 -vcvars_ver=14.3' in vcvars + +@pytest.mark.skipif(platform.system() != "Windows", reason="Requires Windows") +def test_vcvars_compiler_update(): + client = TestClient(path_with_spaces=False) + + conanfile = textwrap.dedent(""" + from conan import ConanFile + class TestConan(ConanFile): + generators = "VCVars" + settings = "os", "compiler", "arch", "build_type" + """) + client.save({"conanfile.py": conanfile}) + client.run('install . -s os=Windows -s compiler=msvc -s compiler.version=193 ' + '-s compiler.cppstd=14 -s compiler.runtime=static ' + '-s compiler.update=3') + + vcvars = client.load("conanvcvars.bat") + assert 'vcvarsall.bat" amd64 -vcvars_ver=14.33' in vcvars + + @pytest.mark.skipif(platform.system() != "Windows", reason="Requires Windows") def test_deactivate_vcvars_message(): client = TestClient() @@ -156,6 +178,7 @@ class TestConan(ConanFile): client.run_command(r'deactivate_conanvcvars.bat') assert "vcvars env cannot be deactivated" in client.out + @pytest.mark.skipif(platform.system() != "Windows", reason="Requires Windows Powershell") def test_deactivate_vcvars_with_powershell(): client = TestClient() diff --git a/conans/test/unittests/tools/cmake/test_cmaketoolchain.py b/conans/test/unittests/tools/cmake/test_cmaketoolchain.py index d231ee8fa68..b08dc13b720 100644 --- a/conans/test/unittests/tools/cmake/test_cmaketoolchain.py +++ b/conans/test/unittests/tools/cmake/test_cmaketoolchain.py @@ -195,7 +195,7 @@ def conanfile_msvc(): c = ConanFile(None) c.settings = Settings({"os": ["Windows"], "compiler": {"msvc": {"version": ["193"], "cppstd": ["20"], - "update": [None]}}, + "update": [None, 8, 9]}}, "build_type": ["Release"], "arch": ["x86"]}) c.settings.build_type = "Release" @@ -220,6 +220,12 @@ def test_toolset(conanfile_msvc): assert 'CMAKE_CXX_STANDARD 20' in toolchain.content +def test_toolset_update_version(conanfile_msvc): + conanfile_msvc.settings.compiler.update = "8" + toolchain = CMakeToolchain(conanfile_msvc) + assert 'set(CMAKE_GENERATOR_TOOLSET "v143,version=14.38" CACHE STRING "" FORCE)' in toolchain.content + + def test_toolset_x64(conanfile_msvc): # https://github.com/conan-io/conan/issues/11144 conanfile_msvc.conf.define("tools.cmake.cmaketoolchain:toolset_arch", "x64")