[gobject-introspection] windows: fix build using subprojects with python >=3.8



commit becb4fa339e8d3774cf106df4dbbf75a8a1e5d4f
Author: Andoni Morales Alastruey <amorales fluendo com>
Date:   Thu Jan 27 15:04:03 2022 +0100

    windows: fix build using subprojects with python >=3.8
    
    Fixes #416

 giscanner/pkgconfig.py | 10 ++++++++++
 giscanner/utils.py     | 41 +++++++++++++++++++++++++++++++----------
 2 files changed, 41 insertions(+), 10 deletions(-)
---
diff --git a/giscanner/pkgconfig.py b/giscanner/pkgconfig.py
index 66822378..39db41d6 100644
--- a/giscanner/pkgconfig.py
+++ b/giscanner/pkgconfig.py
@@ -50,6 +50,16 @@ def cflags(packages, msvc_syntax=False, ignore_errors=True, command=None):
     return shlex.split(out)
 
 
+def libs_only_L(packages, static=False, msvc_syntax=False, ignore_errors=True, command=None):
+    flags = ['--msvc-syntax'] if msvc_syntax else []
+    if static:
+        flags.append('--static')
+    flags.append('--libs-only-L')
+    flags.extend(packages)
+    out = check_output(flags, ignore_errors, command)
+    return shlex.split(out)
+
+
 def libs(packages, msvc_syntax=False, ignore_errors=True, command=None):
     flags = ['--msvc-syntax'] if msvc_syntax else []
     flags.append('--libs')
diff --git a/giscanner/utils.py b/giscanner/utils.py
index 45807f17..31c7ea48 100644
--- a/giscanner/utils.py
+++ b/giscanner/utils.py
@@ -26,6 +26,7 @@ import shutil
 import sys
 import time
 import giscanner.pkgconfig
+from typing import Dict
 
 
 _debugflags = None
@@ -272,12 +273,26 @@ def rmtree(*args, **kwargs):
             return
 
 
+class Singleton(type):
+    '''
+    A helper class to be used as metaclass to implement a singleton.
+    '''
+    _instances: Dict[type, object] = {}
+
+    def __call__(cls, *args, **kwargs):
+        if cls not in cls._instances:
+            cls._instances[cls] = super(Singleton, cls).__call__(*args, **kwargs)
+        return cls._instances[cls]
+
+
 # Mainly used for builds against Python 3.8.x and later on Windows where we need to be
 # more explicit on where dependent DLLs are located, via the use of
-# os.add_dll_directory().  So, we make use of the envvar GI_EXTRA_BASE_DLL_DIRS and the
-# newly-added bindir() method of our pkgconfig module to acquire the paths where dependent
-# DLLs could be found.
-class dll_dirs():
+# os.add_dll_directory().
+# To acquire the paths where dependent DLLs could be found we use:
+#  *  The envvar GI_EXTRA_BASE_DLL_DIRS
+#  *  The bindir variable from gio-2.0.pc when dependencies are installed in a prefix
+#  *  -L directories from pkg-config --libs-only-L for uninstalled dependencies
+class dll_dirs(metaclass=Singleton):
     _cached_dll_dirs = None
     _cached_added_dll_dirs = None
 
@@ -290,22 +305,28 @@ class dll_dirs():
         if os.name == 'nt' and hasattr(os, 'add_dll_directory'):
             if 'GI_EXTRA_BASE_DLL_DIRS' in os.environ:
                 for path in os.environ.get('GI_EXTRA_BASE_DLL_DIRS').split(os.pathsep):
-                    if path not in self._cached_dll_dirs:
-                        self._cached_dll_dirs.append(path)
-                        self._cached_added_dll_dirs.append(os.add_dll_directory(path))
+                    self._add_dll_dir(path)
+
+            for path in giscanner.pkgconfig.libs_only_L(pkgs, True):
+                libpath = path.replace('-L', '')
+                self._add_dll_dir(libpath)
 
             for path in giscanner.pkgconfig.bindir(pkgs):
-                if path not in self._cached_dll_dirs:
-                    self._cached_dll_dirs.append(path)
-                    self._cached_added_dll_dirs.append(os.add_dll_directory(path))
+                self._add_dll_dir(path)
 
     def cleanup_dll_dirs(self):
         if self._cached_added_dll_dirs is not None:
             for added_dll_dir in self._cached_added_dll_dirs:
                 added_dll_dir.close()
+            self._cached_added_dll_dirs.clear()
         if self._cached_dll_dirs is not None:
             self._cached_dll_dirs.clear()
 
+    def _add_dll_dir(self, path):
+        if path not in self._cached_dll_dirs:
+            self._cached_dll_dirs.append(path)
+            self._cached_added_dll_dirs.append(os.add_dll_directory(path))
+
 
 # monkey patch distutils.cygwinccompiler
 # somehow distutils returns runtime library only up to


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]