Ruby GObject Bindings Generator

This project aims to provide a code generator for generating ruby bindings for GObjects. This means that you can easily create bindings for your GObjectified library or application for ruby, so that the library (or a plugin system for the application) can be used from ruby. The idea is about the same as generating python bindings with h2def and codegen (tools provided by the GObject python bindings). This tool is more generic than the python one (could be targeting other languages) and should make it easier to manage the bindings.

The tool consists of two modes of operation:

  1. Generate a XML definitions file from one or more C header files containing the class definitions
  2. Generate the bindings C source code from one or more definition files

Generating definition file

To allow easy setup of a definitions file from which the actual bindings can be generated, RbgTool provides a procedure to find GObject classes, enums, flags, class properties and class/object methods in header files. It will scan the provided header files looking for GObject definitions and will try to resolve the necessary information for the definitions file. Although this doesn't necessarily result in a 100% correct definition, it is a good starting point. A description of the XML format can be found at: DefinitionFormat

Generating the actual bindings

The actual bindings are generated from XML definition files (describing the classes, enums... etc) and optionally override files specifying custom behaviour for generating the source code. It does this by running the override files through ERB and providing methods to specify how the code generator should behave (it's for instance possible to override method implementations, provide custom headers, etc). Possibilities of the override files are described at: OverrideSyntax

Example usage

Definition generation

The actual code is generated by RbgTool from a definitions file as described above. When you first start out to write/generate ruby bindings for your project, you can use rbgtool.rb --definition <header files> > lib.defs to let rbgtool try to figure out all your GObject stuff from a set of header files. RbgTool is more than happy to generate a single definition file from multiple headers, but you can also keep all your different types separated by generating a definition file for each.

RbgTool's header scanner is not perfect, and not all GObject information is present in header files (properties for example). It is therefore almost always necessary to edit the definition files after they are generated. See also DefinitionFormat for more information on the actual syntax of the definitions file.

Code generation

After the definition files are correct, it's time to generate the actual code. This is done by invoking rbgtool.rb --binding <definition files> > rblib.c. This command generates all binding code for all the definitions in the specified definition files. Again, you can have one large definition file, or split all your types in multiple definition files. You can then also generate multiple C source files for all these definitions (which might be a good way to keep an overview of your bindings).

Overrides

You probably always need an override file when generating your bindings because you might need to tell RbgTool what the module name is (this is used in generating the function name of the initialize function for the types and methods specified in the definition files) and you might need to explicitly set the namespace of your library. These and other custom settings can be specified by override files (see OverrideSyntax). You can specify these during code generation with --override <file>. In most cases you need to set the module name, the namespace and include some headers containing the C type definitions.

Binding it all together

The code generation process of RbgTool implements an initialization function in which all your GObject types and maybe free methods are defined in one single module. The initialize function will look something like (in this case with module_name 'gtksourceview'):

rbgtksourceview_initialize (VALUE module)
...

Here you see that you need to specify the 'module' in which everything will be bound. There is no Init_<libname> function generated by RbgTool!!! . The reason is that this gives you the flexibility of installing some types in module1 and some in module2. It also makes it possible for say, a plugin system, to dynamically let types be defined in some custom plugin namespace. And third, it makes it possible to install your bindings in an already existing module (such as Gtk!)

When ruby loads a shared library file, it looks for the symbol Init_<libname>, which it then calls to allow initialization of classes, methods etc. This means that you need to implement this function yourself, before you can actually use the bindings. The easiest way to do this is to create a separate C source file, and do something like this:

#include <ruby.h>

// Forward declaration of your initialization function generated by RbgTool
void rbgtksourceview_initialize (VALUE module);

// Forward declaration of mGtk which is a symbol provided by the gtk2 bindings
extern VALUE mGtk;

void
Init_gtksourceview()
{
    // Initialize sourceview in the Gtk module
    rbgtksourceview_initialize (mGtk);
}