File 0001-cargo_wrapper-deduplicate-Libs_private.patch of Package gstreamer-plugins-rs

From 18daf610104acd70aa5a24b63575ab2ab10c7e45 Mon Sep 17 00:00:00 2001
From: "L. E. Segovia" <amy@amyspark.me>
Date: Thu, 27 Mar 2025 20:07:13 -0300
Subject: [PATCH] cargo_wrapper: Deduplicate Libs.private based on
 Requires.private

cargo-c is in charge of generating the .pc files for gst-plugins-rs.
The data it uses for generating Libs.private is supplied by the link
line assembled by rustc itself. However, it is blissfully unaware that
rustc is implicitly duplicating the libraries w.r.t. Requires.private,
as the value of Libs.private comes from the final value generated and
passed to the linker.

The source for the bug referenced below is that by its own nature, Cargo
is non deterministic when building the dependency tree. Coupled with
cargo-c taking this info verbatim, it results in the contents of
the .pc files being non deterministic.

This commit tries to reduce that to the minimum by transforming the
files, taking their Requires.private section and getting the link flags,
then excluding any entries present in these flags from the contents of
Libs.private.

Fixes #599
---
 cargo_wrapper.py | 46 ++++++++++++++++++++++++++++++++++++++++++----
 1 file changed, 42 insertions(+), 4 deletions(-)

diff --git a/cargo_wrapper.py b/cargo_wrapper.py
index c169045cc..75b652b7d 100644
--- a/cargo_wrapper.py
+++ b/cargo_wrapper.py
@@ -1,7 +1,5 @@
 #!/usr/bin/env python3
 
-import hashlib
-import re
 import glob
 import os
 import shutil
@@ -30,6 +28,41 @@ PARSER.add_argument('--depfile')
 PARSER.add_argument('--disable-doc', action="store_true", default=False)
 
 
+def find_pkgconfig_key(lines: list[str], variable: str):
+    for i in lines:
+        if i.startswith(variable):
+            return i.split(':', maxsplit=1)[1].strip()
+    return None
+
+
+def query_libraries_from_requires(entry: str, env):
+    try:
+        contents = subprocess.check_output(["/usr/bin/pkg-config", "--static", "--libs", entry], text=True, env=env).strip().split()
+    except subprocess.CalledProcessError:
+        return None
+    return set(contents)
+
+
+def transform_file_dedup_libraries(file, env):
+    '''
+    Removes duplicate entries in Libs.private that are already supplied by Requires.private
+    '''
+    contents = open(file, 'r', encoding='utf-8').read().splitlines(keepends=True)
+    libs_private = find_pkgconfig_key(contents, 'Libs.private')
+    requires_private = find_pkgconfig_key(contents, 'Requires.private')
+    if libs_private and requires_private:
+        requires_private = query_libraries_from_requires(requires_private, env)
+        if not requires_private:
+            return # libsodium-sys does not generate a pc file
+        libs_private = [i for i in libs_private.split() if i not in requires_private]
+        with open(file, 'w', encoding='utf-8') as dstfile:
+            for line in contents:
+                if line.startswith('Libs.private: '):
+                    dstfile.write(f"Libs.private: {' '.join(libs_private)}\n")
+                else:
+                    dstfile.write(line)
+
+
 def shlex_join(args):
     if hasattr(shlex, 'join'):
         return shlex.join(args)
@@ -123,7 +156,7 @@ if __name__ == "__main__":
         sys.exit(1)
 
     if rustc_target:
-        cargo_cmd += ['--target', rustc_target]
+        cargo_cmd += ['+nightly', '--target', rustc_target, '-Zbuild-std']
     if features:
         cargo_cmd += ['--features', ','.join(features)]
     cargo_cmd += ['--target-dir', cargo_target_dir]
@@ -187,6 +220,11 @@ if __name__ == "__main__":
         for f in glob.glob(str(target_dir / '*.pc'), recursive=True):
             shutil.copy(f, opts.build_dir)
 
+        # Now that they're inplace, fix them up
+        for f in glob.glob(str(target_dir / '*.pc'), recursive=True):
+            dstfile = os.path.join(opts.build_dir, os.path.basename(f))
+            transform_file_dedup_libraries(dstfile, env)
+
         # Move -uninstalled.pc to meson-uninstalled
         uninstalled = opts.build_dir / 'meson-uninstalled'
         os.makedirs(uninstalled, exist_ok=True)
@@ -201,4 +239,4 @@ if __name__ == "__main__":
                 shutil.move(f, uninstalled)
             else:
                 shutil.move(str(f), str(uninstalled))
-
+            transform_file_dedup_libraries(dest, env)
-- 
GitLab

openSUSE Build Service is sponsored by