From 791ddc485a56933300920ed7a891f77e68c168c3 Mon Sep 17 00:00:00 2001 From: Tibor Harsszegi Date: Fri, 2 Aug 2024 19:33:26 +0200 Subject: [PATCH 1/3] Issue with 'automatic' compatible packages and custom package ids In case the recipe uses its own package_id() and compatible packages are generated automatically (e.g. Visual Studio vs msvc), then the compatible packages will use wrong 'base' info set for the compatible package id generation. In case the recipe's own package_id() erases a few options / settings, the compatible packages will not know about it, as those are generated prior the recipe's package_id() is being called. The change makes sure that first the recipe's package_id() is called, then the compatible packages are generated, so that they pick up the updated info set. --- conans/client/graph/graph_binaries.py | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) 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: From 157bfe0d91a6619d4dd16339cef4f25fe2ede7a2 Mon Sep 17 00:00:00 2001 From: memsharded Date: Mon, 12 Aug 2024 13:11:24 +0200 Subject: [PATCH 2/3] test that crashes --- .../integration/package_id/compatible_test.py | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) 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") From 581ad5810d6cb4aaa6c6c0c17bb4326b7ef7cf12 Mon Sep 17 00:00:00 2001 From: Tibor Harsszegi Date: Tue, 13 Aug 2024 16:37:29 +0200 Subject: [PATCH 3/3] Making sure msvc_compatible handling partially set compiler settings In case a custom package_id() erased some of the compiler settings for 'msvc', a 'Visual Studio' equivalent should be created that also doesn't have the (possibly) erased elements. --- conans/model/info.py | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) 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