Repository: conan-io/conan
Pull request #17568 (2025-01-14 08:39:29)

small refactor to PkgConfigDeps
Changelog: Omit
Docs: Omit


Pure refactor, while trying to implement replace_requires fixes



Patch:
diff --git a/conan/tools/gnu/pkgconfigdeps.py b/conan/tools/gnu/pkgconfigdeps.py
index 561085bd0..0bcaaf5b3 100644
--- a/conan/tools/gnu/pkgconfigdeps.py
+++ b/conan/tools/gnu/pkgconfigdeps.py
@@ -16,6 +16,15 @@ _PCInfo = namedtuple("PCInfo", ['name', 'version', 'requires', 'description',
                                 'cpp_info', 'aliases', 'custom_content'])
 
 
+def alias_content(name, version, aliased):
+    return textwrap.dedent(f"""\
+        Name: {name}
+        Description: Alias {name} for {aliased}
+        Version: {version}
+        Requires: {aliased}
+        """)
+
+
 class _PCContentGenerator:
 
     template = textwrap.dedent("""\
@@ -55,8 +64,6 @@ class _PCContentGenerator:
         """
         prefix_path = self._get_prefix_path()
         pc_variables = {"prefix": prefix_path}
-        if cpp_info is None:
-            return pc_variables
         # Already formatted directories
         pc_variables.update(self._get_formatted_dirs("libdir", cpp_info.libdirs, prefix_path))
         pc_variables.update(self._get_formatted_dirs("includedir", cpp_info.includedirs, prefix_path))
@@ -81,12 +88,13 @@ class _PCContentGenerator:
     def _get_lib_flags(self, libdirvars, cpp_info):
         gnudeps_flags = GnuDepsFlags(self._conanfile, cpp_info)
         libdirsflags = ['-L"${%s}"' % d for d in libdirvars]
-        system_libs = ["-l%s" % l for l in (cpp_info.libs + cpp_info.system_libs)]
+        system_libs = ["-l%s" % li for li in (cpp_info.libs + cpp_info.system_libs)]
         shared_flags = cpp_info.sharedlinkflags + cpp_info.exelinkflags
         framework_flags = gnudeps_flags.frameworks + gnudeps_flags.framework_paths
         return " ".join(libdirsflags + system_libs + shared_flags + framework_flags)
 
-    def _get_cflags(self, includedirvars, cpp_info):
+    @staticmethod
+    def _get_cflags(includedirvars, cpp_info):
         includedirsflags = ['-I"${%s}"' % d for d in includedirvars]
         cxxflags = [var.replace('"', '\\"') for var in cpp_info.cxxflags]
         cflags = [var.replace('"', '\\"') for var in cpp_info.cflags]
@@ -114,16 +122,11 @@ class _PCContentGenerator:
             "version": info.version,
             "requires": info.requires,
             "pc_variables": pc_variables,
-            "cflags": "",
-            "libflags": ""
-        }
-        if info.cpp_info is not None:
-            context.update({
-                "cflags": self._get_cflags([d for d in pc_variables if d.startswith("includedir")],
-                                           info.cpp_info),
-                "libflags": self._get_lib_flags([d for d in pc_variables if d.startswith("libdir")],
-                                                info.cpp_info)
-            })
+            "cflags": self._get_cflags([d for d in pc_variables if d.startswith("includedir")],
+                                       info.cpp_info),
+            "libflags": self._get_lib_flags([d for d in pc_variables if d.startswith("libdir")],
+                                            info.cpp_info)
+            }
         return context
 
     def content(self, info):
@@ -141,7 +144,6 @@ class _PCGenerator:
         self._properties = pkgconfigdeps._properties  # noqa
         self._require = require
         self._dep = dep
-        self._content_generator = _PCContentGenerator(self._conanfile, self._dep)
         self._transitive_reqs = get_transitive_requires(self._conanfile, dep)
         self._is_build_context = require.build
         self._build_context_folder = pkgconfigdeps.build_context_folder
@@ -258,38 +260,33 @@ class _PCGenerator:
 
         * Apart from those PC files, if there are any aliases declared, they will be created too.
         """
-        def _fill_pc_files(pc_info):
-            content = self._content_generator.content(pc_info)
+        def _file_name(name):
             # If no suffix is defined, we can save the *.pc file in the build_context_folder
-            if self._is_build_context and self._build_context_folder and not self._suffix:
-                # Issue: https://github.com/conan-io/conan/issues/12342
-                # Issue: https://github.com/conan-io/conan/issues/14935
-                pc_files[f"{self._build_context_folder}/{pc_info.name}.pc"] = content
-            else:
-                # Saving also the suffixed names as usual
-                pc_files[f"{pc_info.name}.pc"] = content
+            build = self._is_build_context and self._build_context_folder and not self._suffix
+            # Issue: https://github.com/conan-io/conan/issues/12342
+            # Issue: https://github.com/conan-io/conan/issues/14935
+            return f"{self._build_context_folder}/{name}.pc" if build else f"{name}.pc"
+
+        def _add_pc_files(pc_info):
+            content_generator = _PCContentGenerator(self._conanfile, self._dep)
+            result = {_file_name(pc_info.name): content_generator.content(pc_info)}
+            for alias in pc_info.aliases:
+                result[_file_name(alias)] = alias_content(alias, pc_info.version, pc_info.name)
+            return result
 
-        def _update_pc_files(info):
-            _fill_pc_files(info)
-            for alias in info.aliases:
-                alias_info = _PCInfo(alias, self._dep.ref.version, [info.name],
-                                     f"Alias {alias} for {info.name}", None, [], None)
-                _fill_pc_files(alias_info)
-
-        pc_files = {}
         # If the package has no components, then we have to calculate only the root pc file
         if not self._dep.cpp_info.has_components:
-            package_info = self._package_info()
-            _update_pc_files(package_info)
-            return pc_files
+            pkg_pc_info = self._package_info()
+            return _add_pc_files(pkg_pc_info)
 
         # First, let's load all the components PC files
         # Loop through all the package's components
+        pc_files = {}
         pkg_requires = []
-        for component_info in self._components_info():
-            _update_pc_files(component_info)
+        for comp_pc_info in self._components_info():
+            pc_files.update(_add_pc_files(comp_pc_info))
             # Saving components name as the package requires
-            pkg_requires.append(component_info.name)
+            pkg_requires.append(comp_pc_info.name)
 
         # Second, let's load the root package's PC file ONLY
         # if it does not already exist in components one
@@ -303,7 +300,7 @@ class _PCGenerator:
                                    pkg_requires, f"Conan package: {pkg_name}",
                                    self._dep.cpp_info, self._get_package_aliases(self._dep),
                                    self.get_property("pkg_config_custom_content", self._dep))
-            _update_pc_files(package_info)
+            pc_files.update(_add_pc_files(package_info))
         return pc_files
 
     @staticmethod


Test patch:
diff --git a/test/integration/toolchains/gnu/test_pkgconfigdeps.py b/test/integration/toolchains/gnu/test_pkgconfigdeps.py
index 7284a382f..7af64850c 100644
--- a/test/integration/toolchains/gnu/test_pkgconfigdeps.py
+++ b/test/integration/toolchains/gnu/test_pkgconfigdeps.py
@@ -496,8 +496,6 @@ def test_pkg_config_name_full_aliases():
 
     pc_content = client.load("compo1_alias.pc")
     content = textwrap.dedent(f"""\
-    {prefix}
-
     Name: compo1_alias
     Description: Alias compo1_alias for compo1
     Version: 0.3
@@ -525,8 +523,6 @@ def test_pkg_config_name_full_aliases():
 
     pc_content = client.load("pkg_alias1.pc")
     content = textwrap.dedent(f"""\
-    {prefix}
-
     Name: pkg_alias1
     Description: Alias pkg_alias1 for pkg_other_name
     Version: 0.3
@@ -536,8 +532,6 @@ def test_pkg_config_name_full_aliases():
 
     pc_content = client.load("pkg_alias2.pc")
     content = textwrap.dedent(f"""\
-    {prefix}
-
     Name: pkg_alias2
     Description: Alias pkg_alias2 for pkg_other_name
     Version: 0.3