gobject-introspection r962 - in trunk: . giscanner



Author: johan
Date: Sun Nov 23 21:38:08 2008
New Revision: 962
URL: http://svn.gnome.org/viewvc/gobject-introspection?rev=962&view=rev

Log:
2008-11-23  Johan Dahlin  <jdahlin async com br>

        * giscanner/dumper.py: Add license headers,
        refactor into a class, avoid some duplication and do some
        extra pedantic checks.



Modified:
   trunk/ChangeLog
   trunk/giscanner/dumper.py

Modified: trunk/giscanner/dumper.py
==============================================================================
--- trunk/giscanner/dumper.py	(original)
+++ trunk/giscanner/dumper.py	Sun Nov 23 21:38:08 2008
@@ -1,3 +1,24 @@
+# -*- Mode: Python -*-
+# GObject-Introspection - a framework for introspecting GObject libraries
+# Copyright (C) 2008 Colin Walters
+# Copyright (C) 2008 Johan Dahlin
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the
+# Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+#
+
 import os
 import subprocess
 import tempfile
@@ -8,19 +29,8 @@
 # Compile a binary program which is then linked to a library
 # we want to introspect, in order to call its get_type functions.
 
-
-def mktmp(tmpdir, nsname, nsver, suffix):
-    name = '%s-%s%s' % (nsname, nsver, suffix)
-    return os.path.join(tmpdir, name)
-
-
-def compile_introspection_binary(options):
-    tmpdir = tempfile.mkdtemp('', 'tmp-introspect')
-    nsname = options.namespace_name
-    nsver = options.namespace_version
-    c_path = mktmp(tmpdir, nsname, nsver, '.c')
-    f = open(c_path, 'w')
-    f.write('''#include <glib.h>
+_PROGRAM_TEMPLATE = '''/* This file is generated, do not edit */
+#include <glib.h>
 #include <girepository.h>
 #include <string.h>
 
@@ -50,64 +60,133 @@
     }
   return 0;
 }
-''')
-    f.close()
+'''
+
+
+class CompilerError(Exception):
+    pass
+
+
+class LinkerError(Exception):
+    pass
+
+
+class DumpCompiler(object):
+
+    def __init__(self, options):
+        self._options = options
+        self._tmpdir = tempfile.mkdtemp('', 'tmp-introspect')
 
-    o_path = mktmp(tmpdir, nsname, nsver, '.o')
+        self._compiler_cmd = os.environ.get('CC', 'gcc')
+        self._linker_cmd = os.environ.get('LD', self._compiler_cmd)
+        self._pkgconfig_cmd = os.environ.get('PKG_CONFIG', 'pkg-config')
+
+        self._uninst_srcdir = os.environ.get(
+            'UNINSTALLED_INTROSPECTION_SRCDIR')
+        self._packages = ['gio-2.0 gthread-2.0']
+        if not self._uninst_srcdir:
+            self._packages.append('gobject-introspection-1.0')
+
+    # Public API
+
+    def run(self):
+        c_path = self._generate_tempfile('.c')
+        f = open(c_path, 'w')
+        f.write(_PROGRAM_TEMPLATE)
+        f.close()
+
+        o_path = self._generate_tempfile('.o')
+        bin_path = self._generate_tempfile()
+
+        try:
+            self._compile(o_path, c_path)
+        except CompilerError, e:
+            raise SystemExit('ERROR: ' + str(e))
+
+        try:
+            self._link(bin_path, o_path)
+        except LinkerError, e:
+            raise SystemExit('ERROR: ' + str(e))
+
+        os.unlink(c_path)
+
+        return IntrospectionBinary([bin_path], self._tmpdir)
+
+    # Private API
+
+    def _generate_tempfile(self, suffix=''):
+        tmpl = '%s-%s%s' % (self._options.namespace_name,
+                            self._options.namespace_version, suffix)
+        return os.path.join(self._tmpdir, tmpl)
+
+    def _run_pkgconfig(self, flag):
+        proc = subprocess.Popen(
+            [self._pkgconfig_cmd, flag] + self._packages,
+            stdout=subprocess.PIPE)
+        return proc.communicate()[0].split()
+
+    def _use_libtool_infection(self):
+        libtool_infection = not self._options.nolibtool
+        if not libtool_infection:
+            return False
 
-    cc = os.environ.get('CC', 'gcc')
-    ld = os.environ.get('LD', cc)
-    pkgconfig = os.environ.get('PKG_CONFIG', 'pkg-config')
-    uninst_srcdir = os.environ.get('UNINSTALLED_INTROSPECTION_SRCDIR')
-    uninst_builddir = os.environ.get('UNINSTALLED_INTROSPECTION_BUILDDIR')
-
-    pkgs = ['gio-2.0 gthread-2.0']
-    if not uninst_srcdir:
-        pkgs.append('gobject-introspection-1.0')
-
-    cc_args = [cc]
-    if cc == 'gcc':
-        cc_args.append('-Wall')
-    output = subprocess.Popen([pkgconfig, '--cflags'] + pkgs,
-                              stdout=subprocess.PIPE).communicate()[0]
-    if uninst_srcdir:
-        cc_args.append('-I' + os.path.join(uninst_srcdir, 'girepository'))
-    cc_args.extend(output.split())
-    for include in options.cpp_includes:
-        cc_args.append('-I' + include)
-    cc_args.extend(['-c', '-o', o_path, c_path])
-    subprocess.check_call(cc_args)
-
-    bin_path = mktmp(tmpdir, nsname, nsver, '')
-
-    ld_args = [ld, '-o', bin_path, o_path]
-    libtool_infection = not options.nolibtool
-    if not libtool_infection:
         try:
             subprocess.check_call(['libtool', '--version'])
         except subprocess.CalledProcessError, e:
             # If libtool's not installed, assume we don't need it
-            libtool_infection = False
-    if libtool_infection:
-        ld_args.insert(0, 'libtool')
-        ld_args.insert(1, '--mode=link')
-    output = subprocess.Popen([pkgconfig, '--libs'] + pkgs,
-                              stdout=subprocess.PIPE).communicate()[0]
-    ld_args.extend(output.split())
-
-    # This hack is only for building gobject-introspection itself
-    if uninst_builddir:
-        path = os.path.join(uninst_builddir, 'girepository',
-                            'libgirepository.la')
-        ld_args.append(path)
-    # Search the current directory first
-    ld_args.append('-L.')
-
-    # We only use the first library; assume others are "custom" libraries like
-    # from gir-repository.  Right now those don't define new GTypes, so we
-    # don't need to introspect them.
-    ld_args.append('-l'+options.libraries[0])
-    subprocess.check_call(ld_args)
+            return False
+
+        return True
 
-    os.unlink(c_path)
-    return IntrospectionBinary([bin_path], tmpdir)
+    def _compile(self, output, *sources):
+        args = [self._compiler_cmd]
+        if self._compiler_cmd == 'gcc':
+            args.append('-Wall')
+        pkgconfig_flags = self._run_pkgconfig('--cflags')
+        if self._uninst_srcdir:
+            args.append('-I' + os.path.join(self._uninst_srcdir,
+                                               'girepository'))
+        args.extend(pkgconfig_flags)
+        for include in self._options.cpp_includes:
+            args.append('-I' + include)
+        args.extend(['-c', '-o', output])
+        for source in sources:
+            if not os.path.exists(source):
+                raise CompilerError(
+                    "Could not find c source file: %s" % (source, ))
+        args.extend(list(sources))
+        subprocess.check_call(args)
+
+    def _link(self, output, *sources):
+        args = []
+        if self._use_libtool_infection():
+            args.extend(['libtool', '--mode=link'])
+
+        args.extend([self._linker_cmd, '-o', output])
+        args.extend(self._run_pkgconfig('--libs'))
+        for source in sources:
+            if not os.path.exists(source):
+                raise CompilerError(
+                    "Could not find object file: %s" % (source, ))
+        args.extend(list(sources))
+
+        uninst_builddir = os.environ.get('UNINSTALLED_INTROSPECTION_BUILDDIR')
+        # This hack is only for building gobject-introspection itself
+        if uninst_builddir:
+            path = os.path.join(uninst_builddir, 'girepository',
+                                'libgirepository.la')
+            args.append(path)
+
+        # Search the current directory first
+        args.append('-L.')
+
+        # We only use the first library; assume others are "custom" libraries
+        # like from gir-repository.  Right now those don't define new GTypes,
+        # so we don't need to introspect them.
+        args.append('-l' + self._options.libraries[0])
+        subprocess.check_call(args)
+
+
+def compile_introspection_binary(options):
+    dc = DumpCompiler(options)
+    return dc.run()



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