After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 782091 - Incomplete introspection data for libtracker-sparql
Incomplete introspection data for libtracker-sparql
Status: RESOLVED FIXED
Product: tracker
Classification: Core
Component: General
unspecified
Other Linux
: Normal normal
: ---
Assigned To: tracker-general
tracker-general
Depends on:
Blocks:
 
 
Reported: 2017-05-02 22:57 UTC by Sam Thursfield
Modified: 2017-08-03 18:57 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
Python script to merge two .gir files into a single .gir file. (Possibly incomplete) (1.08 KB, text/x-python)
2017-05-02 22:57 UTC, Sam Thursfield
  Details
WIP modification to Autotools build system to combine the namespaces (3.05 KB, patch)
2017-05-02 23:07 UTC, Sam Thursfield
none Details | Review
POC: libtracker-sparql: Generate gir from C sources. (4.90 KB, patch)
2017-05-21 17:17 UTC, Carlos Garnacho
none Details | Review
Fix missing introspection data for libtracker-sparql (when using Meson) (16.72 KB, patch)
2017-06-23 19:00 UTC, Sam Thursfield
committed Details | Review
libtracker-sparql: Drop needless typedef (1.04 KB, patch)
2017-06-27 22:31 UTC, Carlos Garnacho
committed Details | Review
autotools: Build and merge C/Vala girs in libtracker-sparql (9.31 KB, patch)
2017-06-27 22:31 UTC, Carlos Garnacho
committed Details | Review
g-ir-merge: Use env to locate python3 (717 bytes, patch)
2017-08-03 18:50 UTC, Carlos Garnacho
committed Details | Review

Description Sam Thursfield 2017-05-02 22:57:05 UTC
Created attachment 350908 [details]
Python script to merge two .gir files into a single .gir file. (Possibly incomplete)

See mailing list posts for background:

 - https://mail.gnome.org/archives/tracker-list/2017-March/msg00017.html
 - https://mail.gnome.org/archives/tracker-list/2017-April/msg00026.html

After discussion on https://bugzilla.gnome.org/show_bug.cgi?id=781354 I think the best solution is to modify g-ir-compiler to accept multiple .gir files on the commandline and output a .typelib that contains both namespaces.
Comment 1 Sam Thursfield 2017-05-02 23:07:09 UTC
Created attachment 350909 [details] [review]
WIP modification to Autotools build system to combine the namespaces

I tried to do a quick fix using a Python script that can merge two .gir files into a single one that we can then pass to g-ir-compiler.

This should work, but there's a problem: the Vala compiler seems to base the GIR namespace on the filename of the .gir file. So if you pass `--gir Tracker_Vala-1.0.gir` to the Vala compiler, it creates a .gir with a namespace `Tracker_Vala`, which makes no sense. However, if the final GIR file is called Tracker-1.0.gir then we can't also have `valac` generate a file with that name.
Comment 2 Sam Thursfield 2017-05-02 23:07:45 UTC
Carlos pointed out that we may be able to get valac to generate all of the introspection data by writing an appropriate .vapi file. That's worth investigating too.
Comment 3 Jens Georg 2017-05-03 10:15:11 UTC
Possibly one could use vapigen to generate the vapi from the first C-based intermediate gir, then use that as an input for valac to generate a final GIR?

Unless simple, manually writing vapi is rather annyoing.
Comment 4 Sam Thursfield 2017-05-20 17:16:33 UTC
I had a look at writing a .vapi file that describes the C API, but any source file with a .vapi extension is treated as an "external package" and thus its symbols don't get included in the generated .gir file.

Renaming the file to .vala and making the symbols `extern` is more promising, but still doesn't seem to work.

I included this in the Vala build as tracker-sparql-ccode.vala:

[CCode (cprefix = "Tracker", gir_namespace = "Tracker", gir_version = "1.0", lower_case_cprefix = "tracker_")]
namespace Tracker {
    [CCode (cheader_filename = "libtracker-sparql/tracker-sparql.h")]
    public class Resource : GLib.Object {
        public extern Resource (string? identifier);
        public extern void set_gvalue (string property_uri, GLib.Value value);
    }
}

This causes a build failure because now the header file generated by Vala contains a duplicate definition of the TrackerResource class.

I think the only option is going to be modifying g-ir-compiler to merge multiple .gir files into a single .typelib
Comment 5 Carlos Garnacho 2017-05-21 17:17:34 UTC
(In reply to Sam Thursfield from comment #4)
> 
> I think the only option is going to be modifying g-ir-compiler to merge
> multiple .gir files into a single .typelib

IIUC the mapping between gir and typelib files is 1:1 (a typelib being just a binary representation of a gir), we also have to install both for development purposes.

I think we have to join at the .gir level, I still can think of a couple of options to achieve this that just involve changes on our side:

1) Rely on g-ir-scanner fully to generate the gir file out of the *.[ch] files, we already have gtk-doc style comments in the .vala files that get copied as-is to the generated C files, so we can as well add any missing introspection annotations to them.

2) Resort to sed/xslt surgery to merge the gir generated by valac with the missing annotations from g-ir-scanner.

I'm attaching a POC patch doing the first that seems to work, it also includes a hack that I needed for g-ir-scanner to work with TrackerNotifier, because it uses the tracker_sparql_connection_get() symbol that's only defined later at src/libtracker-sparql-backend/, and need one way or another :(. For master, I think it'd make sense to move this folder to src/libtracker-sparql/backends/ or somesuch.
Comment 6 Carlos Garnacho 2017-05-21 17:17:59 UTC
Created attachment 352310 [details] [review]
POC: libtracker-sparql: Generate gir from C sources.
Comment 7 Carlos Garnacho 2017-05-21 17:21:24 UTC
(In reply to Carlos Garnacho from comment #5)
> (In reply to Sam Thursfield from comment #4)
> > 
> > I think the only option is going to be modifying g-ir-compiler to merge
> > multiple .gir files into a single .typelib
> 
> IIUC the mapping between gir and typelib files is 1:1 (a typelib being just
> a binary representation of a gir), we also have to install both for
> development purposes.

And I missed the bug/ML links you provided. Anyway just throwing ideas here, maybe some sticks :).

> 
> I think we have to join at the .gir level, I still can think of a couple of
> options to achieve this that just involve changes on our side:
> 
> 1) Rely on g-ir-scanner fully to generate the gir file out of the *.[ch]
> files, we already have gtk-doc style comments in the .vala files that get
> copied as-is to the generated C files, so we can as well add any missing
> introspection annotations to them.
> 
> 2) Resort to sed/xslt surgery to merge the gir generated by valac with the
> missing annotations from g-ir-scanner.
> 
> I'm attaching a POC patch doing the first that seems to work, it also
> includes a hack that I needed for g-ir-scanner to work with TrackerNotifier,
> because it uses the tracker_sparql_connection_get() symbol that's only
> defined later at src/libtracker-sparql-backend/, and need one way or another
> :(. For master, I think it'd make sense to move this folder to
> src/libtracker-sparql/backends/ or somesuch.
Comment 8 Daniel Espinosa 2017-05-27 00:48:03 UTC
May GXml can help here.

GIR can be modeled in GXml's Serialization GOM framework. Is really easy using Vala.

Gom allows to read strings and add nodes to other. Each node(s) can be imported, to produce a unique GIR to be used by typelib compiler.

All these using DOM4 GObject API.

I was thinking to do so any way. May could be useful for Vala API autocomplation or some thing else, wanting to access gir files using a GObject API.

I've developed gresg to produce gresources from a list of files, using GXml's GOM.
Comment 9 Daniel Espinosa 2017-05-27 03:31:15 UTC
For your problem about Gir namespace, you should use Vala annotations at namespace level like:

https://git.gnome.org/browse/gxml/tree/gxml/namespace-info.vala.in
Comment 10 Sam Thursfield 2017-06-23 09:59:36 UTC
Thanks Daniel. The problem is that if we run `valac --gir=Tracker_Vala-1.0.gir` for example then the namespace in the filename overrides the `[CCode (gir_namespace = "Tracker", gir_version = "1.0")]` annotations that we have in `src/libtracker-sparql/tracker-namespace.vala`.

If we did use a custom GIR XML munger than we'd be able to fix that up on the way, so I guess I should indeed look at doing things that way. Would using GXml be easier than Python's various XML modules ? I certainly want to avoid the insanity of xsltproc if possible :-)
Comment 11 Daniel Espinosa 2017-06-23 15:56:14 UTC
Firs all, Vala GIR for Tracker should be the same name as its namespace, so, Tracker-1.0.gir, this is required for all other libraries out there.

Your Vala GIR should be generated in a different directory, may this is the real problem, I haven't tested if --gir=dir/Tracker-1.0.gir works.

Now considering we have two files with the same name Tracker-1.0.gir we want to merge symbols and lets think we have a GXml model for a GIR file to get datafrom (well this is not really necessary but useful for other applications), lets say we will write this code:

for (int i = 0; i < gir1.symbols.length; i++) {
  // Get one symbol from a source GIR file
  var s = gir1.symbols.get_item (i) as Symbol;
  if (s == null) continue;
  // Create a new symbol node for GIR file to merge symbols to
  var ns = gir2.symbols.create_item () as Symbol;
  // Serialize source symbol and deserialize to destiny symbol to merge
  ns.read_from_string (s.write_string ());
  gir2.symbols.append (ns); // merge deserialized symbol to destiny GIR file
}
// Once done write destiny GIR file
gir2.write_file (destiny_file);


Please note that Symbol may will have a different name, depending on modelled API.

Same process could be done but just using "node_name" property from DOM4 API, for each node, so, just interested nodes should be merged, using a very similar steps.

Is important to note that write_string() method is a GomElement one and it will write a string representation of all child nodes in actual element node, so just taking top level nodes (childs nodes of <namespace> node), you will get all its childs nodes added to new deserialized node.
Comment 12 Sam Thursfield 2017-06-23 19:00:29 UTC
Created attachment 354340 [details] [review]
Fix missing introspection data for libtracker-sparql (when using Meson)

Up til now only the Tracker.SparqlConnection and Tracker.SparqlBuilder
resources were introspectable. This is because we only used the
introspection output from `valac`, but other bits of libtracker-sparql
have since been added that are written in C.

There seems to be no way to generate a single .gir for a combined C and
Vala codebase, so instead I have written a simple `g-ir-merge` script
which can combine two different namespaces into a single .gir.

This is currently tested and working with the Meson build instructions.
It would be possible to implement this for the Autotools build
instructions as well.
Comment 13 Carlos Garnacho 2017-06-26 11:06:56 UTC
Review of attachment 354340 [details] [review]:

If we have to stick to a build time dependency, I indeed prefer it to be python, as it's more ubiquitous than GXml (sorry Daniel, and thanks for helping on the brainstorming :). I think we should also do "the right thing" with autotools though, since I'm still generating tarballs from there.

Besides that I just have cosmetic comments.

::: utils/g-ir-merge/g-ir-merge
@@ +24,3 @@
+libtracker-sparql written in both C and Vala. It's not possible to generate
+a single .gir for all of this code as `g-ir-scanner` can't deal with Vala's
+generated .c code, and `valac` only handles .vala code.

FWIW, the "g-ir-scanner can't deal with Vala generated code" is not quite true, the proof-of-concept patch I attached to this bug went that way with some degree of success. We also have gtk-doc style comments in Vala code that get included as is in generated C code, and we should probably be adding any missing introspection annotations for documentation purposes anyway.

The only thing I saw breaking with that patch are the static symbols that get defined as virtual in src/libtracker-sparql/tracker-connection.vala, but are actually implemented in src/libtracker-sparql-backend/tracker-backend.vala, because we build the gir at an intermediate step before generating the full libtracker-sparql.so in src/libtracker-sparql-backend. That could be presumably fixed if we shuffled all of libtracker-bus,libtracker-direct,libtracker-remote and libtracker-sparql-backend into libtracker-sparql/[bus|direct|remote], which I would like it to eventually happen.

But your solution sounds acceptable IMHO, and doesn't require us to rush major code shuffling in to get introspection working, so take nothing of this comment as an argument against it.

@@ +41,3 @@
+def argument_parser():
+    parser = argparse.ArgumentParser(
+        description="Merge .gir repostories together.")

typo: repositories

@@ +60,3 @@
+
+    This does no post-processing of the data, it simply returns everything
+    including any duplicate or contractory info.

I think this is just fine. If there is such info things will fail quite earlier at link time.

BTW, typo: contradictory :)

@@ +127,3 @@
+    '''Create a new GI repository with a single namespace.'''
+    ElementTree.register_namespace(
+        '', 'http://www.gtk.org/introspection/core/1.0')

The namespace strings seem used in a couple of places, might be better to define those as variables so the string itself is in a single place?
Comment 14 Carlos Garnacho 2017-06-27 22:31:12 UTC
Created attachment 354590 [details] [review]
libtracker-sparql: Drop needless typedef

We don't need defining TrackerSparqlBuilder here, and it causes it
to get picked up twice in C and Vala girs.
Comment 15 Carlos Garnacho 2017-06-27 22:31:18 UTC
Created attachment 354591 [details] [review]
autotools: Build and merge C/Vala girs in libtracker-sparql

Following the meson changes, build 2 separate static libs, generate
introspection stuff for those, and put them together in
src/libtracker-sparql-backend.
Comment 16 Carlos Garnacho 2017-06-28 10:07:10 UTC
Pushed the patches to master \o/. Thanks to everyone involved!

Attachment 354340 [details] pushed as 796e025 - Fix missing introspection data for libtracker-sparql (when using Meson)
Attachment 354590 [details] pushed as 0da7438 - libtracker-sparql: Drop needless typedef
Attachment 354591 [details] pushed as 0348492 - autotools: Build and merge C/Vala girs in libtracker-sparql
Comment 17 Ting-Wei Lan 2017-08-03 13:27:55 UTC
Comment on attachment 354340 [details] [review]
Fix missing introspection data for libtracker-sparql (when using Meson)

Can we use '#!/usr/bin/env python3' instead of '#!/usr/bin/python3' here to make it work on systems installing python to different prefixes? FreeBSD doesn't include python in its base, and all python packages use /usr/local prefix by default.

/bin/sh: ../../utils/g-ir-merge/g-ir-merge: not found
Comment 18 Carlos Garnacho 2017-08-03 18:50:00 UTC
The following fix has been pushed:
4187ceb g-ir-merge: Use env to locate python3
Comment 19 Carlos Garnacho 2017-08-03 18:50:06 UTC
Created attachment 356886 [details] [review]
g-ir-merge: Use env to locate python3

Pointed out to fix build on FreeBSD, since python is not
in /usr/bin.
Comment 20 Carlos Garnacho 2017-08-03 18:57:02 UTC
Thanks for the heads up :)