summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristoph Reiter <reiter.christoph@gmail.com>2022-07-19 09:23:00 +0200
committerChristoph Reiter <reiter.christoph@gmail.com>2022-07-19 22:18:41 +0200
commita3fa882fc9ddce54c51a75f4625b2a3a4170a7a0 (patch)
tree0cf555acd06262e94c637832f302f48d94860e7b
parentdd5dd6d1e10fd2dc793f8a9f0d4c95d4ff88c08f (diff)
downloadgobject-introspection-a3fa882fc9ddce54c51a75f4625b2a3a4170a7a0.tar.gz
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.
-rw-r--r--giscanner/ccompiler.py48
1 files changed, 38 insertions, 10 deletions
diff --git a/giscanner/ccompiler.py b/giscanner/ccompiler.py
index 7a1e9393..2912fe0e 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: