[gobject-introspection] resolve_windows_libs: add llvm/mingw support



commit a3fa882fc9ddce54c51a75f4625b2a3a4170a7a0
Author: Christoph Reiter <reiter christoph gmail com>
Date:   Tue Jul 19 09:23:00 2022 +0200

    resolve_windows_libs: add llvm/mingw support
    
    The existing code tries to mirror how the linker finds DLLs by
    searching for the import libs and then looking for the matching
    shared lib name.
    
    While llvm has a dlltool clone it doesn't provide the --identify
    option to extract the shared lib name. Instead we use the fact that
    llvm import libs include the dll name in the archive member name, so
    we can use "nm" there to get the same result.
    
    To decide which strategy to use we run dlltool and check if it contains
    "llvm-dlltool" in the output.
    
    This fixes the .gir and .typelib files containing bogus values for the
    shared library names when building with clang + mingw-w64 on Windows.
    
    I'm not quite sure if the libtool part is actually needed there,
    but I left it in to keep the diff small.

 giscanner/ccompiler.py | 48 ++++++++++++++++++++++++++++++++++++++----------
 1 file changed, 38 insertions(+), 10 deletions(-)
---
diff --git a/giscanner/ccompiler.py b/giscanner/ccompiler.py
index 7a1e93938..2912fe0e0 100644
--- a/giscanner/ccompiler.py
+++ b/giscanner/ccompiler.py
@@ -95,6 +95,41 @@ def customize_compiler(compiler):
         compiler.shared_lib_extension = shlib_suffix
 
 
+def resolve_mingw_lib(implib, libtool=None):
+    """Returns a DLL name given a path to an import lib
+
+    /full/path/to/libgtk-3.dll.a -> libgtk-3-0.dll
+    """
+
+    args = []
+    if libtool:
+        args.extend(libtool)
+        args.append('--mode=execute')
+
+    # Figure out if we have a gcc toolchain or llvm one
+    dlltool = os.environ.get('DLLTOOL', 'dlltool.exe')
+    dlltool_output = subprocess.run(
+        [dlltool], stdout=subprocess.PIPE,
+        stderr=subprocess.STDOUT,
+        universal_newlines=True).stdout
+    is_llvm = 'llvm-dlltool' in dlltool_output
+
+    if not is_llvm:
+        # gcc dlltool provides this via --identify
+        dlltool_args = args + [dlltool, '--identify']
+        output = subprocess.check_output(dlltool_args + [implib], universal_newlines=True)
+        for line in output.splitlines():
+            return line
+    else:
+        # for llvm we need to parse the output of nm
+        # https://github.com/msys2/MINGW-packages/issues/11994#issuecomment-1176691216
+        output = subprocess.check_output(args + ['nm', implib], universal_newlines=True)
+        for line in output.splitlines():
+            if line.endswith(':'):
+                return line[:-1]
+    return None
+
+
 # Flags that retain macros in preprocessed output.
 FLAGS_RETAINING_MACROS = ['-g3', '-ggdb3', '-gstabs3', '-gcoff3', '-gxcoff3', '-gvms3']
 
@@ -341,10 +376,6 @@ class CCompiler(object):
         # When we are not using Visual C++ nor clang-cl (i.e. we are using GCC)...
         else:
             libtool = utils.get_libtool_command(options)
-            if libtool:
-                args.extend(libtool)
-                args.append('--mode=execute')
-            args.extend([os.environ.get('DLLTOOL', 'dlltool.exe'), '--identify'])
             proc = subprocess.Popen([self.compiler_cmd, '-print-search-dirs'],
                                     stdout=subprocess.PIPE)
             o, e = proc.communicate()
@@ -400,13 +431,10 @@ class CCompiler(object):
                             tmp_fileobj.close()
                             os.unlink(tmp_filename)
                         else:
-                            proc = subprocess.Popen(args + [implib],
-                                                    stdout=subprocess.PIPE)
-                            o, e = proc.communicate()
-                            for line in o.decode('ascii').splitlines():
-                                shlibs.append(line)
+                            shlib = resolve_mingw_lib(implib, libtool)
+                            if shlib is not None:
+                                shlibs.append(shlib)
                                 found = True
-                                break
             if not found:
                 not_resolved.append(lib)
         if len(not_resolved) > 0:


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