Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOwen W. Taylor <otaylor@fishsoup.net>2009-02-16 21:52:52 (GMT)
committer Owen W. Taylor <otaylor@fishsoup.net>2009-02-19 17:05:10 (GMT)
commitec3bcb29fb938ac3d0ea70c1b739a76970613403 (patch)
treeca9b66c1652fc85fd7421097a9886a285f6ba247
parent8b1299bec2c976420bc987daf25ad74d9b615d55 (diff)
Bug 572075 - Make the scanner work with static and convenience libraries
We need to reference the get_type() functions we are going to dlsym or otherwise the linker may not include them in the introspection binary. giscanner/dumper.py: Accept a list of _get_type() functions and write an array referencing them into the introspection binary. giscanner/glibtransformer.py: Break parsing into too stages - the stage where we compute the _get_type() functions and the stage where we invoke the introspection binary. tools/g-ir-scanner: Pass _get_type() functions from the scanner when creating the introspection binary. http://bugzilla.gnome.org/show_bug.cgi?id=572075
-rw-r--r--giscanner/dumper.py23
-rw-r--r--giscanner/glibtransformer.py23
-rwxr-xr-xtools/g-ir-scanner16
3 files changed, 49 insertions, 13 deletions
diff --git a/giscanner/dumper.py b/giscanner/dumper.py
index 6b78568..e487c12 100644
--- a/giscanner/dumper.py
+++ b/giscanner/dumper.py
@@ -73,8 +73,9 @@ class LinkerError(Exception):
class DumpCompiler(object):
- def __init__(self, options):
+ def __init__(self, options, get_type_functions):
self._options = options
+ self._get_type_functions = get_type_functions
self._tmpdir = tempfile.mkdtemp('', 'tmp-introspect')
self._compiler_cmd = os.environ.get('CC', 'gcc')
@@ -93,6 +94,22 @@ class DumpCompiler(object):
c_path = self._generate_tempfile('.c')
f = open(c_path, 'w')
f.write(_PROGRAM_TEMPLATE)
+
+ # We need to reference our get_type functions to make sure they are
+ # pulled in at the linking stage if the library is a static library
+ # rather than a shared library.
+ for func in self._get_type_functions:
+ f.write("extern GType " + func + "(void);\n")
+ f.write("GType (*GI_GET_TYPE_FUNCS_[])(void) = {\n")
+ first = True
+ for func in self._get_type_functions:
+ if first:
+ first = False
+ else:
+ f.write(",\n")
+ f.write(" " + func)
+ f.write("\n};\n")
+
f.close()
o_path = self._generate_tempfile('.o')
@@ -208,6 +225,6 @@ class DumpCompiler(object):
subprocess.check_call(args)
-def compile_introspection_binary(options):
- dc = DumpCompiler(options)
+def compile_introspection_binary(options, get_type_functions):
+ dc = DumpCompiler(options, get_type_functions)
return dc.run()
diff --git a/giscanner/glibtransformer.py b/giscanner/glibtransformer.py
index f05ce65..c39ce64 100644
--- a/giscanner/glibtransformer.py
+++ b/giscanner/glibtransformer.py
@@ -99,9 +99,6 @@ class GLibTransformer(object):
# Public API
- def set_introspection_binary(self, binary):
- self._binary = binary
-
def _print_statistics(self):
nodes = list(self._names.names.itervalues())
@@ -114,9 +111,16 @@ class GLibTransformer(object):
print " %d nodes; %d objects, %d interfaces, %d enums" \
% (len(nodes), objectcount, ifacecount, enumcount)
- def parse(self):
+ def init_parse(self):
+ """Do parsing steps that don't involve the introspection binary
+
+ This does enough work that get_type_functions() can be called.
+
+ """
+
namespace = self._transformer.parse()
self._namespace_name = namespace.name
+ self._namespace_version = namespace.version
# First pass: parsing
for node in namespace.nodes:
@@ -127,6 +131,15 @@ class GLibTransformer(object):
if namespace.name == 'GObject':
del self._names.aliases['Type']
+ def get_get_type_functions(self):
+ return self._get_type_functions
+
+ def set_introspection_binary(self, binary):
+ self._binary = binary
+
+ def parse(self):
+ """Do remaining parsing steps requiring introspection binary"""
+
# Get all the GObject data by passing our list of get_type
# functions to the compiled binary
@@ -158,7 +171,7 @@ class GLibTransformer(object):
self._validate(nodes)
# Create a new namespace with what we found
- namespace = Namespace(namespace.name, namespace.version)
+ namespace = Namespace(self._namespace_name, self._namespace_version)
namespace.nodes = map(lambda x: x[1], self._names.aliases.itervalues())
for (ns, x) in self._names.names.itervalues():
namespace.nodes.append(x)
diff --git a/tools/g-ir-scanner b/tools/g-ir-scanner
index 0cf54ce..f53f7fc 100755
--- a/tools/g-ir-scanner
+++ b/tools/g-ir-scanner
@@ -316,17 +316,23 @@ def main(args):
# Transform the C symbols into AST nodes
transformer.set_source_ast(ss)
+ # Transform the C AST nodes into higher level
+ # GLib/GObject nodes
+ glibtransformer = GLibTransformer(transformer,
+ noclosure=options.noclosure)
+
+ # Do enough parsing that we have the get_type() functions to reference
+ # when creating the introspection binary
+ glibtransformer.init_parse()
+
if options.program:
args=[options.program]
args.extend(options.program_args)
binary = IntrospectionBinary(args)
else:
- binary = compile_introspection_binary(options)
+ binary = compile_introspection_binary(options,
+ glibtransformer.get_get_type_functions())
- # Transform the C AST nodes into higher level
- # GLib/GObject nodes
- glibtransformer = GLibTransformer(transformer,
- noclosure=options.noclosure)
glibtransformer.set_introspection_binary(binary)
namespace = glibtransformer.parse()