Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[bug] cpp_info.requires fails when the same replacement is used multiple times in [replace_requires] #17316

Open
valgur opened this issue Nov 13, 2024 · 2 comments
Assignees

Comments

@valgur
Copy link
Contributor

valgur commented Nov 13, 2024

Describe the bug

Conan: 2.9.2
OS: Linux

When using the following [replace_requires] in the host profile (for cross-compilation, since system libs are not available there):

[replace_requires]
opengl/system: libglvnd/1.7.0
egl/system: libglvnd/1.7.0
glu/system: libglvnd/1.7.0

this version of libepoxy fails during the package_info() step with the following error:

ERROR: libepoxy/1.5.10: required component package 'egl::' not in dependencies

This only happens when both opengl/system and egl/system are being used simultaneously. The error disappears when either one of the dependencies is removed from either self.requires() or self.cpp_info.requires.

The error does not occur when self.cpp_info.requires is left unset entirely.

How to reproduce it

Here's a minimal example:

from conan import ConanFile

class EpoxyConan(ConanFile):
    name = "libepoxy"
    version = "0.1"
    settings = "os", "arch", "compiler", "build_type"

    def requirements(self):
        self.requires("opengl/system")
        self.requires("egl/system")

    def package_info(self):
        self.cpp_info.requires.append("opengl::opengl")
        self.cpp_info.requires.append("egl::egl")

and a sample profile:

[settings]
arch=x86_64
build_type=Release
compiler=gcc
compiler.cppstd=17
compiler.libcxx=libstdc++11
compiler.version=11
os=Linux

[conf]
tools.build:compiler_executables={"c": "gcc-11", "cpp": "g++-11"}

[replace_requires]
opengl/system: libglvnd/1.7.0
egl/system: libglvnd/1.7.0
glu/system: libglvnd/1.7.0
@valgur valgur changed the title cpp_info.requires fails when the same replacement is used multiple times in [replace_requires] [bug] cpp_info.requires fails when the same replacement is used multiple times in [replace_requires] Nov 13, 2024
@memsharded memsharded self-assigned this Nov 14, 2024
@valgur
Copy link
Contributor Author

valgur commented Nov 15, 2024

diff --git a/conans/model/dependencies.py b/conans/model/dependencies.py
--- a/conans/model/dependencies.py	(revision fabc81498dd673a03fd86326e6c3e858f1f7c3cc)
+++ b/conans/model/dependencies.py	(date 1731674551386)
@@ -91,12 +91,15 @@
     def from_node(node):
         d = OrderedDict((require, ConanFileInterface(transitive.node.conanfile))
                         for require, transitive in node.transitive_deps.items())
+        cleanup = set()
         for old_req, new_req in node.replaced_requires.items():
-            existing = d.pop(new_req, None)
-            if existing is not None:
-                added_req = new_req.copy_requirement()
-                added_req.ref = RecipeReference.loads(old_req)
-                d[added_req] = existing
+            added_req = new_req.copy_requirement()
+            added_req.ref = RecipeReference.loads(old_req)
+            d[added_req] = d[new_req]
+            if added_req != new_req:
+                cleanup.add(new_req)
+        for new_req in cleanup:
+            del d[new_req]
         return ConanFileDependencies(d)
 
     def filter(self, require_filter, remove_system=True):

This current logic is broken if a new_req value is present multiple times in node.replaced_requires:

>> list(d)
[
    'libglvnd/1.7.0',
    'xorg/system',
    'xorg-proto/2024.1',
    'xorg-macros/1.20.0',
]
>> node.replaced_requires
{
    'egl/system': 'libglvnd/1.7.0',
    'opengl/system': 'libglvnd/1.7.0',
}

The added_req != new_req check is necessary for replace_requires like xorg/system: xorg/1.8.10, which don't change the ref name and evaluate to the same d dictionary item. These would otherwise get incorrectly removed by del d[new_req].

@memsharded
Copy link
Member

Thanks for the hint @valgur!

I already started to work on it the other day, see develop2...memsharded:conan:fix/replace_requires_multiple (I think it was a couple of days ago), but I am out of office in a conference and I didn't have the time to report here.
I'll try to move it forward for next release, I'll try to summarize work after the weekend.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants