ianprime0509 / zig-gobject

GObject bindings for Zig using GObject introspection
http://ianjohnson.dev/zig-gobject/
BSD Zero Clause License
52 stars 6 forks source link
bindings gobject gtk gui zig

zig-gobject

Bindings for GObject-based libraries (such as GTK) generated using GObject introspection data.

Usage

To use the bindings, find the latest release of this project and add the desired bindings artifact as a dependency in build.zig.zon. Then, the exposed bindings can be used as modules. For example:

const gobject = b.dependency("gobject", .{});
exe.root_module.addImport("gtk", gobject.module("gtk-4.0"));
exe.root_module.addImport("adw", gobject.module("adw-1"));

The binding generator and generated bindings are tested on Zig 0.13.0 and master, though support for the latest master may temporarily regress when breaking changes are made upstream.

Companion projects

Examples

There are several examples in the example directory, which is itself a runnable project (depending on the bindings directory as a dependency). After generating the bindings, the examples can be run using zig build run in the example directory.

Development environment

The bindings generated by this project cover a wide variety of libraries, and it can be annoying and inconvenient to install these libraries on a host system for testing purposes. The best way to get a consistent environment for testing is to use Flatpak:

  1. Install flatpak.
  2. Install the GNOME SDK: flatpak install org.gnome.Sdk//47

The steps above only need to be done once per GNOME SDK version. To enter a development environment:

  1. Run flatpak run --filesystem=home --share=network --share=ipc --socket=fallback-x11 --socket=wayland --device=dri --socket=session-bus org.gnome.Sdk//47
    • --filesystem=home - makes the user's home directory available within the container
    • --share=network - allows network access (needed to fetch build.zig.zon dependencies)
    • --share=ipc --socket=fallback-x11 --socket=wayland --device=dri - allows graphical display through X11 or Wayland
    • --socket=session-bus - allows access to the session bus
    • For convenience, this command is available as a script in this repository: flatpak-env.sh.
  2. Within the spawned shell, you can use the latest master version of Zig downloaded from ziglang.org. Since the downloaded Zig is statically linked, it is usable within the Flatpak environment with no additional setup.

Running the binding generator

The binding generator can be invoked using zig build codegen, which accepts several useful options and is described further below, or by building the translate-gir binary using zig build and invoking it directly.

zig build codegen requires a set of modules to be used as input. The input modules can be specified using -Dmodules to provide an explicit list of root modules for codegen (the codegen process will also discover any necessary dependencies): for example, zig build codegen -Dmodules=Gtk-4.0 will generate bindings for GTK 4 and anything else it depends on (Gio, GObject, GLib, and many others).

Alternatively, if a Flatpak development environment is set up (see the section above), a predefined GIR profile can be selected using -Dgir-profile, which includes all the modules available in a specific GNOME SDK. The predefined profiles track the latest two GNOME releases.

GIR files are assumed to be located in /usr/share/gir-1.0 unless this is overridden via -Dgir-files-path.

The bindings are generated to the bindings directory under the build prefix (by default, zig-out).

Fixing broken GIR files

Sometimes, there are errors in GIR files which result in incorrect or incomplete bindings. The codegen process can handle this via XSLT stylesheets, which are named after the modules whose GIR files they correct. This project maintains stylesheets fixing known GIR issues in gir-fixes.

The XSLT stylesheets are applied using the xsltproc program, which is part of the libxslt project. At this time, this is a system command dependency; there is no support yet for building xsltproc from source due to https://github.com/ianprime0509/zig-libxml2/issues/1

Writing bindings by hand

While the binding generator is capable of generating good bindings from GIR input, it is sometimes necessary or desirable to bypass GIR for everything except build-related metadata (library dependencies, etc.) and write Zig bindings by hand. This is the strategy taken for Cairo, using the Cairo bindings in binding-overrides.

Any manual binding files present in binding-overrides will cause codegen of bindings to be skipped for the corresponding modules, using the manual bindings instead.

Running tests

zig build test will run the binding generator's tests. If bindings have been generated, the test project directory contains a package depending on them which runs tests on the generated bindings. The zig build test command in the test project accepts the same modules and gir-profile options as the codegen command to specify which modules to test (unlike codegen, the modules option here specifies a complete list of modules to test: there is no discovery and testing of dependency modules).

Further reading

License

This project is released under the Zero-Clause BSD License. The libraries exposed by the generated bindings are subject to their own licenses.