diff options
author | Christoph Reiter <reiter.christoph@gmail.com> | 2022-07-19 09:23:00 +0200 |
---|---|---|
committer | Christoph Reiter <reiter.christoph@gmail.com> | 2022-07-19 22:18:41 +0200 |
commit | a3fa882fc9ddce54c51a75f4625b2a3a4170a7a0 (patch) | |
tree | 0cf555acd06262e94c637832f302f48d94860e7b /giscanner | |
parent | dd5dd6d1e10fd2dc793f8a9f0d4c95d4ff88c08f (diff) | |
download | gobject-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.
Diffstat (limited to 'giscanner')
-rw-r--r-- | giscanner/ccompiler.py | 48 |
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: |