diff --git a/conans/client/conf/compiler_id.py b/conans/client/conf/compiler_id.py index 9fa32e50036..da9adee0591 100644 --- a/conans/client/conf/compiler_id.py +++ b/conans/client/conf/compiler_id.py @@ -11,10 +11,11 @@ CLANG = "clang" APPLE_CLANG = "apple-clang" SUNCC = "suncc" -MSVC = "Visual Studio" +VISUAL_STUDIO = "Visual Studio" INTEL = "intel" QCC = "qcc" MCST_LCC = "mcst-lcc" +MSVC = "msvc" class CompilerId(object): @@ -135,21 +136,28 @@ def _parse_compiler_version(defines): patch = version & 0xF # MSVC goes after Clang and Intel, as they may define _MSC_VER elif '_MSC_VER' in defines: - compiler = MSVC version = int(defines['_MSC_VER']) - # map _MSC_VER into conan-friendly Visual Studio version - # currently, conan uses major only, but here we store minor for the future as well - # https://docs.microsoft.com/en-us/cpp/preprocessor/predefined-macros?view=vs-2019 - major, minor = MSVC_TO_VS_VERSION.get(version) - # special cases 19.8 and 19.9, 19.10 and 19.11 full_version = 0 if '_MSC_FULL_VER' in defines: full_version = int(defines['_MSC_FULL_VER']) - if (major, minor) == (16, 8) and full_version >= 192829500: - major, minor = 16, 9 - if (major, minor) == (16, 10) and full_version >= 192930100: - major, minor = 16, 11 - patch = 0 + # Visual Studio 2022 onwards, detect as a new compiler "msvc" + if version >= 1930: + compiler = MSVC + major = int(version / 100) + minor = int(version % 100) + patch = int(full_version % 100000) + else: + compiler = VISUAL_STUDIO + # map _MSC_VER into conan-friendly Visual Studio version + # currently, conan uses major only, but here we store minor for the future as well + # https://docs.microsoft.com/en-us/cpp/preprocessor/predefined-macros?view=vs-2019 + major, minor = MSVC_TO_VS_VERSION.get(version) + # special cases 19.8 and 19.9, 19.10 and 19.11 + if (major, minor) == (16, 8) and full_version >= 192829500: + major, minor = 16, 9 + if (major, minor) == (16, 10) and full_version >= 192930100: + major, minor = 16, 11 + patch = 0 # GCC must be the last try, as other compilers may define __GNUC__ for compatibility elif '__GNUC__' in defines: if '__llvm__' in defines: diff --git a/conans/client/conf/detect.py b/conans/client/conf/detect.py index 71f54a8a703..005604fee20 100644 --- a/conans/client/conf/detect.py +++ b/conans/client/conf/detect.py @@ -160,6 +160,10 @@ def _get_profile_compiler_version(compiler, version, output): return major elif compiler == "intel" and (int(major) < 19 or (int(major) == 19 and int(minor) == 0)): return major + elif compiler == "msvc": + # by default, drop the last digit of the minor (19.30 -> 19.3) + if len(minor) == 2: + version = version[:-1] return version @@ -224,6 +228,13 @@ def _detect_compiler_version(result, output, profile_path): output.error("Unable to find a working compiler") return + # Visual Studio 2022 onwards, detect as a new compiler "msvc" + if compiler == "Visual Studio": + version = Version(version) + if version == "17": + compiler = "msvc" + version = "19.3" + result.append(("compiler", compiler)) result.append(("compiler.version", _get_profile_compiler_version(compiler, version, output))) diff --git a/conans/test/unittests/client/build/compiler_id_test.py b/conans/test/unittests/client/build/compiler_id_test.py index 34dabe8ce02..ea01fcbdb33 100644 --- a/conans/test/unittests/client/build/compiler_id_test.py +++ b/conans/test/unittests/client/build/compiler_id_test.py @@ -2,7 +2,7 @@ from parameterized import parameterized from conans.client.conf.compiler_id import detect_compiler_id, CompilerId, UNKNOWN_COMPILER, \ - GCC, LLVM_GCC, CLANG, APPLE_CLANG, SUNCC, MSVC, INTEL, QCC, MCST_LCC + GCC, LLVM_GCC, CLANG, APPLE_CLANG, SUNCC, VISUAL_STUDIO, MSVC, INTEL, QCC, MCST_LCC from conans.test.unittests.util.tools_test import RunnerMock @@ -105,13 +105,18 @@ def test_suncc(self): ("MSC_CMD_FLAGS=-D_MSC_VER=1928 -D_MSC_FULL_VER=192829500", 16, 9, 0), ("MSC_CMD_FLAGS=-D_MSC_VER=1929", 16, 10, 0), ("MSC_CMD_FLAGS=-D_MSC_VER=1929 -D_MSC_FULL_VER=192930100", 16, 11, 0), - ("MSC_CMD_FLAGS=-D_MSC_VER=1930", 17, 0, 0), ]) - def test_msvc(self, line, major, minor, patch): + def test_visual_studio(self, line, major, minor, patch): runner = RunnerMock() runner.output = line compiler_id = detect_compiler_id("cl", runner=runner) - self.assertEqual(CompilerId(MSVC, major, minor, patch), compiler_id) + self.assertEqual(CompilerId(VISUAL_STUDIO, major, minor, patch), compiler_id) + + def test_msvc(self): + runner = RunnerMock() + runner.output = "MSC_CMD_FLAGS=-D_MSC_VER=1930" + compiler_id = detect_compiler_id("cl", runner=runner) + self.assertEqual(CompilerId(MSVC, 19, 30, 0), compiler_id) def test_intel(self): runner = RunnerMock() diff --git a/conans/test/unittests/util/detect_test.py b/conans/test/unittests/util/detect_test.py index b65203a070d..07d23670c7f 100644 --- a/conans/test/unittests/util/detect_test.py +++ b/conans/test/unittests/util/detect_test.py @@ -93,3 +93,12 @@ def test_detect_clang_gcc_toolchain(self, _): with tools.environment_append({"CC": "clang-9 --gcc-toolchain=/usr/lib/gcc/x86_64-linux-gnu/9"}): detect_defaults_settings(output, profile_path="./MyProfile") self.assertIn("CC and CXX: clang-9 --gcc-toolchain", output) + + def test_vs2022(self): + with mock.patch("conans.client.conf.detect._get_default_compiler", + mock.MagicMock(return_value=("Visual Studio", "17"))): + result = detect_defaults_settings(output=Mock(), + profile_path=DEFAULT_PROFILE_NAME) + result = dict(result) + self.assertEqual('msvc', result['compiler']) + self.assertEqual('19.3', result['compiler.version'])