diff --git a/conans/client/graph/graph_binaries.py b/conans/client/graph/graph_binaries.py index 8f5a925e33d..fa5a9542f20 100644 --- a/conans/client/graph/graph_binaries.py +++ b/conans/client/graph/graph_binaries.py @@ -394,6 +394,17 @@ def _compute_package_id(self, node, default_package_id_mode, default_python_requ default_python_requires_id_mode= default_python_requires_id_mode) conanfile.original_info = conanfile.info.clone() + + # Call the package id before any compatibility, as the other way around + # compatibile packages will be cloned from a wrong info set. How? + # If the package id erases a few options / settings and it is done AFTER + # compatibility, the compatible packages will still look for packages + # containing those - later erased - options, settings + with conanfile_exception_formatter(str(conanfile), "package_id"): + with conan_v2_property(conanfile, 'cpp_info', + "'self.cpp_info' access in package_id() method is deprecated"): + conanfile.package_id() + if not self._cache.new_config["core.package_id:msvc_visual_incompatible"]: msvc_compatible = conanfile.info.msvc_compatible() if msvc_compatible: @@ -403,12 +414,6 @@ def _compute_package_id(self, node, default_package_id_mode, default_python_requ if apple_clang_compatible: conanfile.compatible_packages.append(apple_clang_compatible) - # Once we are done, call package_id() to narrow and change possible values - with conanfile_exception_formatter(str(conanfile), "package_id"): - with conan_v2_property(conanfile, 'cpp_info', - "'self.cpp_info' access in package_id() method is deprecated"): - conanfile.package_id() - if hasattr(conanfile, "validate") and callable(conanfile.validate): with conanfile_exception_formatter(str(conanfile), "validate"): try: diff --git a/conans/model/info.py b/conans/model/info.py index 0cee4a20ff4..798964708b8 100644 --- a/conans/model/info.py +++ b/conans/model/info.py @@ -600,12 +600,15 @@ def msvc_compatible(self): compatible.settings.compiler.cppstd = cppstd from conan.tools.microsoft.visual import msvc_version_to_vs_ide_version - visual_version = msvc_version_to_vs_ide_version(version) - compatible.settings.compiler.version = visual_version - runtime = "MT" if runtime == "static" else "MD" - if runtime_type == "Debug": - runtime = "{}d".format(runtime) - compatible.settings.compiler.runtime = runtime + if version is not None: + visual_version = msvc_version_to_vs_ide_version(version) + compatible.settings.compiler.version = visual_version + + if runtime is not None and runtime_type is not None: + runtime = "MT" if runtime == "static" else "MD" + if runtime_type == "Debug": + runtime = "{}d".format(runtime) + compatible.settings.compiler.runtime = runtime # Some 'final adjustment' # In case the cppstd is the 'default' for the compiler, it will actually be erased diff --git a/conans/test/integration/package_id/compatible_test.py b/conans/test/integration/package_id/compatible_test.py index 725b723739c..51f361b62d9 100644 --- a/conans/test/integration/package_id/compatible_test.py +++ b/conans/test/integration/package_id/compatible_test.py @@ -771,3 +771,27 @@ def package_info(self): client.run("install . -o pkg/*:optimized=3") assert "pkg/0.1@user/stable: Already installed!" in client.out assert f"pkg/0.1@user/stable:{package_id} - Cache" in client.out + + +def test_crash(): + client = TestClient() + conanfile = textwrap.dedent(""" + from conans import ConanFile + + class Pkg(ConanFile): + settings = "os", "compiler" + def package_id(self): + del self.info.settings.compiler.version + """) + profile = textwrap.dedent(""" + [settings] + os = Windows + compiler=msvc + compiler.version=192 + compiler.runtime=dynamic + compiler.cppstd=14 + build_type=Release + """) + client.save({"conanfile.py": conanfile, + "myprofile": profile}) + client.run("create . pkg/0.1@ -pr=myprofile")