conan-io / conan

Conan - The open-source C and C++ package manager
https://conan.io
MIT License
8.14k stars 970 forks source link

[bug] compatible_packages does not work when used with full_package_mode #11196

Open boussaffawalid opened 2 years ago

boussaffawalid commented 2 years ago

Using the conanfile below, I'm trying to make Debug package compatible with Release.

from conan import ConanFile

class DemoConan(ConanFile):
    name = "demo"
    version = "1.0.0"

    # Binary configuration
    settings = "os", "compiler", "build_type", "arch"
    options = {"shared": [True, False], "fPIC": [True, False]}
    default_options = {"shared": False, "fPIC": True}

    def requirements(self):
        self.requires("openssl/3.0.2")

    def build(self):
        pass

    def package(self):
        pass

    def package_id(self):
        if self.settings.build_type == "Debug":
            compatible_pkg = self.info.clone()
            compatible_pkg.settings.build_type = "Release"
            self.compatible_packages.append(compatible_pkg)
conan create . -s build_type=Release
conan install demo/1.0.0@ -s build_type=Debug

and it works as expected!

I got this in the output,

demo/1.0.0: Main binary package 'b1637c67046517aa98464b47384851bd7e7fcd49' missing. Using compatible package '11f1add483c8e24b17f69a1b8eef4b9630b6f160'

Now I tried to enable full_package_mode in combination with compatible_packages , using the following package_id method.

    def package_id(self):
        self.info.requires.full_package_mode()
        if self.settings.build_type == "Debug":
            compatible_pkg = self.info.clone()
            compatible_pkg.settings.build_type = "Release"
            self.compatible_packages.append(compatible_pkg)

Now it fails with this error:

Installing package: demo/1.0.0
Requirements
    demo/1.0.0 from local cache - Cache
    openssl/3.0.2 from 'conancenter' - Cache
    zlib/1.2.11 from local cache - Cache
Packages
    demo/1.0.0:ddc1cbd4116102e8ac9b9f24efe22b12dc141638 - Missing
    openssl/3.0.2:150778ad56d91e99abe6728021fb5e61699efb30 - Cache
    zlib/1.2.11:d98fae1010d1fb9e7f79a1e8a72bbf129d8660a2 - Cache

Installing (downloading, building) binaries...
ERROR: Missing binary: demo/1.0.0:ddc1cbd4116102e8ac9b9f24efe22b12dc141638

doing some debugging, I figure out that this issue only happens when the recipe have requirements. When I tried to remove self.requires("openssl/3.0.2"), compatible_packages works again as expected when used with full_package_mode

memsharded commented 2 years ago

Hi @boussaffawalid

I can't reproduce this here. Tried this unit test and it is working fine:


def test_full_package_mode():
    # https://github.com/conan-io/conan/issues/11196
    c = TestClient()
    conanfile = textwrap.dedent("""
        from conan import ConanFile
        class DemoConan(ConanFile):
            name = "demo"
            version = "1.0"
            settings = "build_type"
            requires = "dep/1.0"

            def package_id(self):
                self.info.requires.full_package_mode()
                if self.settings.build_type == "Debug":
                    compatible_pkg = self.info.clone()
                    compatible_pkg.settings.build_type = "Release"
                    self.compatible_packages.append(compatible_pkg)
            """)
    c.save({"dep/conanfile.py": GenConanfile("dep", "1.0"),
            "demo/conanfile.py": conanfile})
    c.run("create dep")
    c.run("create demo")
    c.run("install demo/1.0@ -s build_type=Debug")
    assert "Using compatible package" in c.out

Can you please check it? Thanks!

boussaffawalid commented 2 years ago

@memsharded I tried the test you provided and it passes. Could you try the example I provided above ? openssl/3.0.2 is the one from https://conan.io/center/

memsharded commented 2 years ago

Yes, works fine with openssl/3.0.2 too.

boussaffawalid commented 2 years ago

@memsharded I tired on two different machines, macos and windows 10 and I got the same error. I will try again on a fresh installed ubuntu machine.

boussaffawalid commented 2 years ago

@memsharded I created a new ubuntu virtual machine, with freshly installed conan. Still not working, here are the results:

asciicast

memsharded commented 2 years ago

Oh, now I see what you mean, I have been able to reproduce. This is the test:

def test_full_package_mode():
    # https://github.com/conan-io/conan/issues/11196
    c = TestClient()
    c.run("config set general.revisions_enabled=True")
    c.run("remote add center http://center.conan.io")
    conanfile = textwrap.dedent("""
        from conan import ConanFile
        class DemoConan(ConanFile):
            name = "demo"
            version = "1.0"
            settings = "build_type"
            requires = "dep/1.0"

            def package_id(self):
                self.info.requires.full_package_mode()
                if self.settings.build_type == "Debug":
                    compatible_pkg = self.info.clone()
                    compatible_pkg.settings.build_type = "Release"
                    self.compatible_packages.append(compatible_pkg)
            """)
    c.save({"dep/conanfile.py": GenConanfile("dep", "1.0").with_settings("build_type"),
            "demo/conanfile.py": conanfile})
    c.run("create dep")
    c.run("create dep -s build_type=Debug")
    c.run("create demo")
    c.run("install demo/1.0@")
    c.run("install demo/1.0@ -s build_type=Debug", assert_error=True)
    assert "Missing binary" in c.out
    c.run("install demo/1.0@ -s demo:build_type=Debug")
    assert "Using compatible package" in c.out

This is expected behavior. The fact that you are falling back debug->release in the demo package doesn't mean that the package_id for openssl won't be changing when you change configuration. If the openssl package_id changes, and you are factoring it the full reference, include the package_id full_package_mode into the hash of the demo package, when you change openssl from Debug to Release, the package_id of demo changes. As you can see, passing the -s demo:build_type=Debug will make it work.

boussaffawalid commented 2 years ago

@memsharded now it works! thanks! However, I'm still wondering how to achieve this when creating packages using conan-package-tools. Is that even possible ?

memsharded commented 2 years ago

@memsharded now it works! thanks! However, I'm still wondering how to achieve this when creating packages using conan-package-tools. Is that even possible ?

No, I think conan-package-tools does not provision for per-package settings yet, but I am not sure, I don't follow conan-package-tools closely.