diff options
-rw-r--r-- | giscanner/dumper.py | 23 | ||||
-rw-r--r-- | giscanner/glibtransformer.py | 23 | ||||
-rwxr-xr-x | tools/g-ir-scanner | 16 |
3 files changed, 49 insertions, 13 deletions
diff --git a/giscanner/dumper.py b/giscanner/dumper.py index 6b78568c..e487c125 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 f05ce65e..c39ce64c 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 0cf54cec..f53f7fc3 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() |