From 444648d6a8b97250e737bc46d00d8278a5c205d4 Mon Sep 17 00:00:00 2001 From: Chun-wei Fan Date: Tue, 15 Mar 2016 00:58:08 +0800 Subject: ccompiler.py: Win32: Use tempfile for resolving libs When using the NMake Makefile within the Visual Studio projects, as we are using dumpbin to resolve the .lib file that we link to, the outputs of dumpbin is captured by the Visual Studio output panel, which causes it not to be processed by proc.communicate(). This is due to dumpbin being an integrated component of Visual Studio. In order to remedy this, we need to use a temp file, and use the /out: flag, and look for the DLL that is linked to by the .lib that we pass in. https://bugzilla.gnome.org/show_bug.cgi?id=763739 --- giscanner/ccompiler.py | 57 +++++++++++++++++++++++++++++++------------------- 1 file changed, 36 insertions(+), 21 deletions(-) diff --git a/giscanner/ccompiler.py b/giscanner/ccompiler.py index c83bd7ea..25823382 100644 --- a/giscanner/ccompiler.py +++ b/giscanner/ccompiler.py @@ -20,6 +20,7 @@ import os import subprocess +import tempfile import sys import distutils @@ -269,7 +270,11 @@ class CCompiler(object): # Use the dumpbin utility that's included in # every Visual C++ installation to find out which - # DLL the library gets linked to + # DLL the .lib gets linked to. + # dumpbin -symbols something.lib gives the + # filename of DLL without the '.dll' extension that something.lib + # links to, in the line that contains + # __IMPORT_DESCRIPTOR_ args.append('dumpbin.exe') args.append('-symbols') @@ -310,26 +315,36 @@ class CCompiler(object): break implib = os.path.join(l, c) if os.path.exists(implib): - proc = subprocess.Popen(args + [implib], - stdout=subprocess.PIPE) - o, e = proc.communicate() - for line in o.decode('ascii').splitlines(): - if self.check_is_msvc(): - # On Visual Studio, dumpbin -symbols something.lib gives the - # filename of DLL without the '.dll' extension that something.lib - # links to, in the line that contains - # __IMPORT_DESCRIPTOR_ - - if '__IMPORT_DESCRIPTOR_' in line: - line_tokens = line.split() - for item in line_tokens: - if item.startswith('__IMPORT_DESCRIPTOR_'): - shlibs.append(item[20:] + '.dll') - found = True - break - if found: - break - else: + if self.check_is_msvc(): + tmp_fd, tmp_filename = \ + tempfile.mkstemp(prefix='g-ir-win32-resolve-lib-') + + # This is dumb, but it is life... Windows does not like one + # trying to write to a file when its FD is not closed first, + # when we use a flag in a program to do so. So, close, + # write to temp file with dumpbin and *then* re-open the + # file for reading. + os.close(tmp_fd) + output_flag = ['-out:' + tmp_filename] + proc = subprocess.call(args + [implib] + output_flag, + stdout=subprocess.PIPE) + with open(tmp_filename, 'rb') as tmp_fileobj: + for line in tmp_fileobj.read().splitlines(): + + if '__IMPORT_DESCRIPTOR_' in line: + line_tokens = line.split() + for item in line_tokens: + if item.startswith('__IMPORT_DESCRIPTOR_'): + shlibs.append(item[20:] + '.dll') + found = True + break + 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) found = True break -- cgit v1.2.1