summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChun-wei Fan <fanchunwei@src.gnome.org>2014-08-22 18:48:50 +0800
committerChun-wei Fan <fanchunwei@src.gnome.org>2015-07-22 16:11:42 +0800
commit8dbf68dbcc37894705291d4b367a3f5a6fe6f447 (patch)
tree8da9af6b8a3f4fc5576c4e89f3765cbdd8c6448e
parent87fbb721e6562758cfb1677536d0fe65dc66892a (diff)
downloadgobject-introspection-8dbf68dbcc37894705291d4b367a3f5a6fe6f447.tar.gz
giscanner/ccompiler.py: Initiate Distutils Compiler Instance
This updates the __init__ constructor method of CCompiler so that distutils can be used, with some environment or user-supplied options to create the compiler instance that is appropriate with the platform that the giscanner scripts are being run on, and sets some specific environment for the compilers as necessary. This also adds a check_is_msvc() method that will progressively replace calls in the other giscanner scripts that attempt to check for CC=cl (or so), where a part of which is done in this patch. This is done for dumper.py as well as it needs to be updated in this patch to use the updated ccompiler.py which uses distutils to initiate the compiler instance. Also, as we have been using the --library option on Windows to pass in the library (not DLL) to deduce the correct DLL to link to in the introspection files for some time, we no longer need to make a copy of the library (.lib) to introspect that matches the <namespace>-<namespace_version>.lib convention, but use the libraries that were passed in with --library directly, so that we can link the dumper program during the introspection build. https://bugzilla.gnome.org/show_bug.cgi?id=728313
-rw-r--r--giscanner/ccompiler.py129
-rw-r--r--giscanner/dumper.py55
2 files changed, 106 insertions, 78 deletions
diff --git a/giscanner/ccompiler.py b/giscanner/ccompiler.py
index aeaa5b5a..884fc2cc 100644
--- a/giscanner/ccompiler.py
+++ b/giscanner/ccompiler.py
@@ -37,51 +37,85 @@ class CCompiler(object):
compiler = None
_cflags_no_deprecation_warnings = ''
- def __init__(self, compiler_name=None):
- pass
-
- def get_internal_link_flags(self,
- args,
- libtool,
- libraries,
- libpaths,
- pkgconfig_msvc_flags,
- ns,
- ns_version):
+ def __init__(self,
+ environ=os.environ,
+ osname=os.name,
+ compiler_name=None):
+
+ if osname == 'nt':
+ # The compiler used here on Windows may well not be
+ # the same compiler that was used to build Python,
+ # as the official Python binaries are built with
+ # Visual Studio
+ if compiler_name is None:
+ if environ.get('MSYSTEM') == 'MINGW32' or environ.get('MSYSTEM') == 'MINGW64':
+ compiler_name = 'mingw32'
+ else:
+ compiler_name = distutils.ccompiler.get_default_compiler()
+ if compiler_name != 'msvc' and \
+ compiler_name != 'mingw32':
+ raise SystemExit('Specified Compiler \'%s\' is unsupported.' % compiler_name)
+ else:
+ # XXX: Is it common practice to use a non-Unix compiler
+ # class instance on non-Windows on platforms g-i supports?
+ compiler_name = distutils.ccompiler.get_default_compiler()
+
+ # Now, create the distutils ccompiler instance based on the info we have.
+ self.compiler = distutils.ccompiler.new_compiler(compiler=compiler_name)
+ customize_compiler(self.compiler)
+
+ # customize_compiler from distutils only does customization
+ # for 'unix' compiler type. Also, avoid linking to msvcrxx.dll
+ # for MinGW builds as the dumper binary does not link to the
+ # Python DLL, but link to msvcrt.dll if necessary.
+ if isinstance(self.compiler, Mingw32CCompiler):
+ if self.compiler.dll_libraries != ['msvcrt']:
+ self.compiler.dll_libraries = []
+ if self.compiler.preprocessor is None:
+ self.compiler.preprocessor = self.compiler.compiler + ['-E']
+
+ if self.check_is_msvc():
+ # We trick distutils to believe that we are (always) using a
+ # compiler supplied by a Windows SDK, so that we avoid launching
+ # a new build environment to detect the compiler that is used to
+ # build Python itself, which is not desirable, so that we use the
+ # compiler commands (and env) as-is.
+ os.environ['DISTUTILS_USE_SDK'] = '1'
+ if 'MSSdk' not in os.environ:
+ if 'WindowsSDKDir' in os.environ:
+ os.environ['MSSdk'] = os.environ.get('WindowsSDKDir')
+ elif os.environ.get('VCInstallDir'):
+ os.environ['MSSdk'] = os.environ.get('VCInstallDir')
+
+ self.compiler_cmd = 'cl.exe'
+
+ self._cflags_no_deprecation_warnings = "-wd4996"
+ else:
+ if (isinstance(self.compiler, Mingw32CCompiler)):
+ self.compiler_cmd = self.compiler.compiler[0]
+ else:
+ self.compiler_cmd = ''.join(self.compiler.executables['compiler'])
+
+ self._cflags_no_deprecation_warnings = "-Wno-deprecated-declarations"
+
+ def get_internal_link_flags(self, args, libtool, libraries, libpaths):
# An "internal" link is where the library to be introspected
# is being built in the current directory.
# Search the current directory first
# (This flag is not supported nor needed for Visual C++)
- if pkgconfig_msvc_flags == '':
+ if not self.check_is_msvc():
args.append('-L.')
- # https://bugzilla.gnome.org/show_bug.cgi?id=625195
- if not libtool:
- # We don't have -Wl,-rpath for Visual C++, and that's
- # going to cause a problem. Instead, link to internal
- # libraries by deducing the .lib file name using
- # the namespace name and version
- if pkgconfig_msvc_flags:
- if ns_version:
- args.append(str.lower(ns) +
- '-' +
- ns_version + '.lib')
- else:
- args.append(str.lower(ns) + '.lib')
- else:
+ # https://bugzilla.gnome.org/show_bug.cgi?id=625195
+ if not libtool:
args.append('-Wl,-rpath=.')
-
- # Ensure libraries are always linked as we are going to use ldd to work
- # out their names later
- if not libtool and pkgconfig_msvc_flags == '':
- args.append('-Wl,--no-as-needed')
+ args.append('-Wl,--no-as-needed')
for library in libraries:
- # Visual C++: We have the needed .lib files now, and we need to link
- # to .lib files, not the .dll as the --library option specifies the
- # .dll(s) the .gir file refers to
- if pkgconfig_msvc_flags == '':
+ if self.check_is_msvc():
+ args.append(library + '.lib')
+ else:
if library.endswith(".la"): # explicitly specified libtool library
args.append(library)
else:
@@ -90,7 +124,7 @@ class CCompiler(object):
for library_path in libpaths:
# Not used/needed on Visual C++, and -Wl,-rpath options
# will cause grief
- if pkgconfig_msvc_flags == '':
+ if not self.check_is_msvc():
args.append('-L' + library_path)
if os.path.isabs(library_path):
if libtool:
@@ -99,15 +133,15 @@ class CCompiler(object):
else:
args.append('-Wl,-rpath=' + library_path)
- def get_external_link_flags(self, args, libraries, pkgconfig_msvc_flags):
+ def get_external_link_flags(self, args, libraries):
# An "external" link is where the library to be introspected
# is installed on the system; this case is used for the scanning
# of GLib in gobject-introspection itself.
for library in libraries:
- # The --library option on Windows pass in the .dll file(s) the
- # .gir files refer to, so don't link to them on Visual C++
- if pkgconfig_msvc_flags == '':
+ if self.check_is_msvc():
+ args.append(library + '.lib')
+ else:
if library.endswith(".la"): # explicitly specified libtool library
args.append(library)
else:
@@ -115,15 +149,13 @@ class CCompiler(object):
def resolve_windows_libs(self, libraries, options):
args = []
- compiler_cmd = os.environ.get('CC', 'cc')
libsearch = []
# When we are using Visual C++...
- if 'cl.exe' in compiler_cmd or 'cl' in compiler_cmd:
+ if self.check_is_msvc():
# The search path of the .lib's on Visual C++
# is dependent on the LIB environmental variable,
# so just query for that
- is_msvc = True
libpath = os.environ.get('LIB')
libsearch = libpath.split(';')
@@ -135,7 +167,6 @@ class CCompiler(object):
# When we are not using Visual C++ (i.e. we are using GCC)...
else:
- is_msvc = False
libtool = utils.get_libtool_command(options)
if libtool:
args.append(utils.which(os.environ.get('SHELL', 'sh.exe')))
@@ -143,7 +174,7 @@ class CCompiler(object):
args.append('--mode=execute')
# FIXME: it could have prefix (i686-w64-mingw32-dlltool.exe)
args.extend(['dlltool.exe', '--identify'])
- proc = subprocess.Popen([compiler_cmd, '-print-search-dirs'],
+ proc = subprocess.Popen([self.compiler_cmd, '-print-search-dirs'],
stdout=subprocess.PIPE)
o, e = proc.communicate()
for line in o.splitlines():
@@ -175,7 +206,7 @@ class CCompiler(object):
stdout=subprocess.PIPE)
o, e = proc.communicate()
for line in o.splitlines():
- if is_msvc:
+ 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
@@ -201,3 +232,9 @@ class CCompiler(object):
"ERROR: can't resolve libraries to shared libraries: " +
", ".join(not_resolved))
return shlibs
+
+ def check_is_msvc(self):
+ if isinstance(self.compiler, MSVCCompiler):
+ return True
+ else:
+ return False
diff --git a/giscanner/dumper.py b/giscanner/dumper.py
index 45a09fc8..94231771 100644
--- a/giscanner/dumper.py
+++ b/giscanner/dumper.py
@@ -78,25 +78,21 @@ class LinkerError(Exception):
class DumpCompiler(object):
+ _compiler = None
+
def __init__(self, options, get_type_functions, error_quark_functions):
self._options = options
self._get_type_functions = get_type_functions
self._error_quark_functions = error_quark_functions
- self._compiler_cmd = os.environ.get('CC', 'cc')
- self._linker_cmd = os.environ.get('CC', self._compiler_cmd)
+ # Acquire the compiler (and linker) commands via the CCompiler class in ccompiler.py
+ self._compiler = CCompiler()
+
self._pkgconfig_cmd = os.environ.get('PKG_CONFIG', 'pkg-config')
- self._pkgconfig_msvc_flags = ''
- # Enable the --msvc-syntax pkg-config flag when
- # the Microsoft compiler is used
- # (This is the other way to check whether Visual C++ is used subsequently)
- args = self._compiler_cmd.split()
- if 'cl.exe' in args or 'cl' in args:
- self._pkgconfig_msvc_flags = '--msvc-syntax'
- self._uninst_srcdir = os.environ.get(
- 'UNINSTALLED_INTROSPECTION_SRCDIR')
+ self._uninst_srcdir = os.environ.get('UNINSTALLED_INTROSPECTION_SRCDIR')
self._packages = ['gio-2.0 gmodule-2.0']
self._packages.extend(options.packages)
+ self._linker_cmd = os.environ.get('CC', 'cc')
# Public API
@@ -155,7 +151,7 @@ class DumpCompiler(object):
# Microsoft compilers generate intermediate .obj files
# during compilation, unlike .o files like GCC and others
- if self._pkgconfig_msvc_flags:
+ if self._compiler.check_is_msvc():
o_path = self._generate_tempfile(tmpdir, '.obj')
else:
o_path = self._generate_tempfile(tmpdir, '.o')
@@ -193,8 +189,8 @@ class DumpCompiler(object):
def _run_pkgconfig(self, flag):
# Enable the --msvc-syntax pkg-config flag when
# the Microsoft compiler is used
- if self._pkgconfig_msvc_flags:
- cmd = [self._pkgconfig_cmd, self._pkgconfig_msvc_flags, flag]
+ if self._compiler.check_is_msvc():
+ cmd = [self._pkgconfig_cmd, '--msvc-syntax', flag]
else:
cmd = [self._pkgconfig_cmd, flag]
proc = subprocess.Popen(
@@ -204,14 +200,14 @@ class DumpCompiler(object):
def _compile(self, output, *sources):
# Not strictly speaking correct, but easier than parsing shell
- args = self._compiler_cmd.split()
+ args = self._compiler.compiler_cmd.split()
# Do not add -Wall when using init code as we do not include any
# header of the library being introspected
- if self._compiler_cmd == 'gcc' and not self._options.init_sections:
+ if self._compiler.compiler_cmd == 'gcc' and not self._options.init_sections:
args.append('-Wall')
# The Microsoft compiler uses different option flags for
# silencing warnings on deprecated function usage
- if self._pkgconfig_msvc_flags:
+ if self._compiler.check_is_msvc():
args.append("-wd4996")
else:
args.append("-Wno-deprecated-declarations")
@@ -227,7 +223,7 @@ class DumpCompiler(object):
args.append('-I' + include)
# The Microsoft compiler uses different option flags for
# compilation result output
- if self._pkgconfig_msvc_flags:
+ if self._compiler.check_is_msvc():
args.extend(['-c', '-Fe' + output, '-Fo' + output])
else:
args.extend(['-c', '-o', output])
@@ -258,7 +254,7 @@ class DumpCompiler(object):
args.extend(self._linker_cmd.split())
# We can use -o for the Microsoft compiler/linker,
# but it is considered deprecated usage with that
- if self._pkgconfig_msvc_flags:
+ if self._compiler.check_is_msvc():
args.extend(['-Fe' + output])
else:
args.extend(['-o', output])
@@ -288,23 +284,18 @@ class DumpCompiler(object):
"Could not find object file: %s" % (source, ))
args.extend(list(sources))
- cc = CCompiler()
+ pkg_config_libs = self._run_pkgconfig('--libs')
if not self._options.external_library:
- cc.get_internal_link_flags(args,
- libtool,
- self._options.libraries,
- self._options.library_paths,
- self._pkgconfig_msvc_flags,
- self._options.namespace_name,
- self._options.namespace_version)
- args.extend(self._run_pkgconfig('--libs'))
+ self._compiler.get_internal_link_flags(args,
+ libtool,
+ self._options.libraries,
+ self._options.library_paths)
+ args.extend(pkg_config_libs)
else:
- args.extend(self._run_pkgconfig('--libs'))
- cc.get_external_link_flags(args,
- self._options.libraries,
- self._pkgconfig_msvc_flags)
+ args.extend(pkg_config_libs)
+ self._compiler.get_external_link_flags(args, self._options.libraries)
if not self._options.quiet:
print "g-ir-scanner: link: %s" % (