This is how we generate the Vala bindings for poppler-glib. Note that you can only bind GLib-based APIs with the .gi format, for other C libraries you will have to stick to writing vapi manually.
The following example demonstrates how to write poppler-glib bindings for Vala. Poppler has a GLib wrapper, and we're going to use it to generate our own Vala API.
$ vala-gen-introspect Usage: vala-gen-introspect PKGNAME BASEPATH
vala-gen-introspect, the command responsible to generate our .gi interfaces, needs the package development files to be installed.
$ mkdir poppler-glib $ ls poppler-glib
Now, we proceed to generate the gi files:
$ vala-gen-introspect poppler-glib poppler-glib cat: poppler-glib/poppler-glib.files: No such file or directory cat: poppler-glib/poppler-glib.namespace: No such file or directory ERROR: Need at least one header file.
Oops! What's going on here? Let's figure it out... two things are wrong here:
First, it seems that it lacks some filename (poppler-glib.files and poppler-glib.namespace) NOTE: The package name (PKGNAME argument) has to be the same as the pkg-config package file (.pc) of the original library.
vala-gen-introspect is not a so magical tool (yet), you need to provide a list of directories where the glib/gobject source files are stored inside the package and the namespace to populate those files (package.files and package.namespace), the namespace is the prefix used in the functions and struct names.
How do we figure this out? We need to take a look at the headers:
First we figure out the pkg-config package name:
$ ls /usr/lib/pkgconfig/ | grep poppler poppler-cairo.pc poppler-glib.pc poppler.pc poppler-splash.pc
So, poppler-glib is the one we were looking for since it's the library that we're going to bind. Now we need to figure out where the poppler-glib headers and libraries are, in order to populate poppler-glib.files. This file is going to have all the directories with gobject headers and libraries:
$ grep Cflags /usr/lib/pkgconfig/poppler-glib.pc Cflags: -I${includedir}/poppler/glib $ ls /usr/lib/libpoppler*.so /usr/lib/libpoppler-glib.so /usr/lib/libpoppler.so
$(prefix)/include/poppler/glib/ seems a good candidate, isn't it? Okay, now the namespace, that's pretty easy, we only need to look inside some header file, for example, glib/poppler.h:
$ grep 'typedef struct' /usr/include/poppler/glib/poppler.h typedef struct _PopplerDocument PopplerDocument; typedef struct _PopplerIndexIter PopplerIndexIter; typedef struct _PopplerFontsIter PopplerFontsIter; ...
So it seems that the prefix used as source namespace is Poppler, we're ready to generate the .gi file. Remember, we use now the package name for the .files and the .namespace file, and we have to include it after the path:
poppler-0.5.4 $ cd .. $ echo "include/poppler/glib/" > poppler-glib/poppler-glib.files $ echo "lib/libpoppler-glib.so" >> poppler-glib/poppler-glib.files $ echo "Poppler" > poppler-glib/poppler-glib.namespace $ vala-gen-introspect poppler-glib poppler-glib Unknown symbol: GObject Unknown symbol: GObject $ ls poppler-glib/ poppler-glib.files poppler-glib.gi poppler-glib.namespace
So that's it, we've generated our first .gi file!