Skip to content

Commit

Permalink
fix for msvc toolset version overflow (#15588)
Browse files Browse the repository at this point in the history
* fix for msvc toolset version overflow

* review

* wip

* compatibility

* compat only forward

* fixes

* new test for PkgConfigDeps (#16198)

* removed prints
  • Loading branch information
memsharded authored May 13, 2024
1 parent cab4f18 commit 3232cf6
Show file tree
Hide file tree
Showing 8 changed files with 77 additions and 22 deletions.
13 changes: 9 additions & 4 deletions conan/internal/api/detect_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -384,9 +384,14 @@ def detect_default_compiler():
return None, None, None

if platform.system() == "Windows":
compiler, version, compiler_exe = detect_msvc_compiler()
if compiler:
return compiler, version, compiler_exe
ide_version = _detect_vs_ide_version()
version = {"17": "193", "16": "192", "15": "191"}.get(str(ide_version)) # Map to compiler
if ide_version == "17":
update = detect_msvc_update(version) # FIXME weird passing here the 193 compiler version
if update and int(update) >= 10:
version = "194"
if version:
return 'msvc', Version(version), None

if platform.system() == "SunOS":
sun_cc, sun_cc_version, compiler_exe = detect_suncc_compiler()
Expand All @@ -409,7 +414,7 @@ def detect_default_compiler():


def default_msvc_ide_version(version):
version = {"193": "17", "192": "16", "191": "15"}.get(str(version))
version = {"194": "17", "193": "17", "192": "16", "191": "15"}.get(str(version))
if version:
return Version(version)

Expand Down
7 changes: 5 additions & 2 deletions conan/tools/microsoft/visual.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,8 @@ def msvc_version_to_vs_ide_version(version):
'190': '14',
'191': '15',
'192': '16',
'193': '17'}
'193': '17',
'194': '17'} # Note both 193 and 194 belong to VS 17 2022
return _visuals[str(version)]


Expand All @@ -75,7 +76,8 @@ def msvc_version_to_toolset_version(version):
'190': 'v140',
'191': 'v141',
'192': 'v142',
"193": 'v143'}
"193": 'v143',
"194": 'v143'}
return toolsets.get(str(version))


Expand Down Expand Up @@ -140,6 +142,7 @@ def generate(self, scope="build"):
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)
Expand Down
4 changes: 2 additions & 2 deletions conans/client/conf/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,14 +94,14 @@
"10", "10.1", "10.2", "10.3", "10.4", "10.5",
"11", "11.1", "11.2", "11.3", "11.4",
"12", "12.1", "12.2", "12.3",
"13", "13.1", "13.2",
"13", "13.1", "13.2",
"14", "14.1"]
libcxx: [libstdc++, libstdc++11]
threads: [null, posix, win32] # Windows MinGW
exception: [null, dwarf2, sjlj, seh] # Windows MinGW
cppstd: [null, 98, gnu98, 11, gnu11, 14, gnu14, 17, gnu17, 20, gnu20, 23, gnu23]
msvc:
version: [170, 180, 190, 191, 192, 193]
version: [170, 180, 190, 191, 192, 193, 194]
update: [null, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
runtime: [static, dynamic]
runtime_type: [Debug, Release]
Expand Down
2 changes: 1 addition & 1 deletion conans/client/conf/detect_vs.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ def vs_installation_path(version):


def vs_detect_update(version):
version = {"193": "17", "192": "16", "191": "15"}.get(str(version))
version = {"194": "17", "193": "17", "192": "16", "191": "15"}.get(str(version))
full_version = _vs_installation_path(version)[1]
components = full_version.split(".")
if len(components) > 1:
Expand Down
41 changes: 29 additions & 12 deletions conans/client/graph/compatibility.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,26 +30,43 @@ def compatibility(conanfile):
def cppstd_compat(conanfile):
# It will try to find packages with all the cppstd versions
extension_properties = getattr(conanfile, "extension_properties", {})
if extension_properties.get("compatibility_cppstd") is False:
return []
compiler = conanfile.settings.get_safe("compiler")
compiler_version = conanfile.settings.get_safe("compiler.version")
cppstd = conanfile.settings.get_safe("compiler.cppstd")
if not compiler or not compiler_version or not cppstd:
if not compiler or not compiler_version:
return []
base = dict(conanfile.settings.values_list)
cppstd_possible_values = supported_cppstd(conanfile)
if cppstd_possible_values is None:
conanfile.output.warning(f'No cppstd compatibility defined for compiler "{compiler}"')
return []
ret = []
for _cppstd in cppstd_possible_values:
if _cppstd is None or _cppstd == cppstd:
factors = [] # List of list, each sublist is a potential combination
if cppstd is not None and extension_properties.get("compatibility_cppstd") is not False:
cppstd_possible_values = supported_cppstd(conanfile)
if cppstd_possible_values is None:
conanfile.output.warning(f'No cppstd compatibility defined for compiler "{compiler}"')
else:
factors.append([{"compiler.cppstd": v} for v in cppstd_possible_values if v != cppstd])
if compiler == "msvc":
msvc_fallback = {"194": "193"}.get(compiler_version)
if msvc_fallback:
factors.append([{"compiler.version": msvc_fallback}])
combinations = []
for factor in factors:
if not combinations:
combinations = factor
continue
new_combinations = []
for comb in combinations:
for f in factor:
comb = comb.copy()
comb.update(f)
new_combinations.append(comb)
combinations = new_combinations
ret = []
for comb in combinations:
configuration = base.copy()
configuration["compiler.cppstd"] = _cppstd
configuration.update(comb)
ret.append({"settings": [(k, v) for k, v in configuration.items()]})
return ret
"""

Expand Down
21 changes: 21 additions & 0 deletions conans/test/integration/package_id/test_cache_compatibles.py
Original file line number Diff line number Diff line change
Expand Up @@ -377,6 +377,27 @@ def test_unnecessary_builds(self):
c.run("install --requires=app/0.1 --build=missing")
assert re.search(r"Skipped binaries(\s*)tool/0.1", c.out)

def test_msvc_194_fallback(self):
c = TestClient()
save(c.cache.default_profile_path, "")
c.save({"conanfile.py": GenConanfile("mylib", "1.0").with_settings("os", "arch",
"compiler", "build_type"),
"profile_build": "[settings]\nos=Windows\narch=x86_64"})

c.run("create . -s os=Windows -s arch=x86_64 -s build_type=Release "
"-s compiler=msvc "
"-s compiler.version=193 -s compiler.cppstd=17 "
"-s compiler.runtime=dynamic -pr:b=profile_build")
package_id1 = c.created_package_id("mylib/1.0")

# Try to install with cppstd 14, it will find cppstd 17 as compatible
c.run("install --requires=mylib/1.0@ -s os=Windows -s arch=x86_64 -s build_type=Release "
"-s compiler=msvc "
"-s compiler.version=194 -s compiler.cppstd=14 "
"-s compiler.runtime=dynamic -pr:b=profile_build")
assert "mylib/1.0: Main binary package 'e340edd75790e7156c595edebd3d98b10a2e091e' missing."\
f"Using compatible package '{package_id1}'"


class TestErrorsCompatibility:
""" when the plugin fails, we want a clear message and a helpful trace
Expand Down
10 changes: 9 additions & 1 deletion conans/test/unittests/tools/cmake/test_cmaketoolchain.py
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ def test_osx_deployment_target(conanfile_apple):
def conanfile_msvc():
c = ConanFile(None)
c.settings = Settings({"os": ["Windows"],
"compiler": {"msvc": {"version": ["193"], "cppstd": ["20"],
"compiler": {"msvc": {"version": ["193", "194"], "cppstd": ["20"],
"update": [None, 8, 9]}},
"build_type": ["Release"],
"arch": ["x86"]})
Expand Down Expand Up @@ -226,6 +226,14 @@ def test_toolset_update_version(conanfile_msvc):
assert 'set(CMAKE_GENERATOR_TOOLSET "v143,version=14.38" CACHE STRING "" FORCE)' in toolchain.content


def test_toolset_update_version_overflow(conanfile_msvc):
# https://github.com/conan-io/conan/issues/15583
conanfile_msvc.settings.compiler.version = "194"
conanfile_msvc.settings.compiler.update = "8"
toolchain = CMakeToolchain(conanfile_msvc)
assert 'set(CMAKE_GENERATOR_TOOLSET "v143,version=14.48" 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")
Expand Down
1 change: 1 addition & 0 deletions conans/test/unittests/tools/microsoft/test_msvs_toolset.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ def test_invalid_compiler():


@pytest.mark.parametrize("compiler_version,expected_toolset", [
("194", "v143"),
("193", "v143"),
("192", "v142"),
("191", "v141"),
Expand Down

0 comments on commit 3232cf6

Please sign in to comment.