gir2objc is a utility that generates Objective-C language bindings for GNOME GLib/Gobject based libraries using GObject Introspection (GOI), which it does by parsing GIR files.
It is the heart of the ObjGTK project, which is a fork of CoreGTK, originally created by Tyler Burton, now in use with ObjFW by Jonathan Schleifer.
ObjGTK and gir2objc are based on Codeberg. You will need a Codeberg account to submit and respond to issues.
- Objective-C API generation on a class level for any GObject based library that provides a proper GIR file
- generated API wraps GObject in-parameters and return types of methods using Objective-C wrapper classes and
gchar
types usingOFString
- recursive generation for library dependencies
- writing out documentation for classes and methods
- error handling using ObjFW exceptions
- memory management for GObject based classes providing manual reference counting (MRC) on library level using toggle references on GObject side
- ARC (automatic reference counting) on application level is possible using clang
- generic way of signal binding thanks to contributors
- compatibility with gcc should be given currently (but providing only limited ObjC features of gcc, often called "Objective-C 2.0")
- unwanted library dependencies may be excluded via configuration
- unwanted (f.e. internal) classes may be excluded via configuration
- configuration for renaming libraries
- manual implementations of classes (or categories…) are added to the generated ones when placed in the
LibrarySourceAdditions
directory - generation of build files for each generated library that makes use of the very portable autoconf and ObjFW buildsys
- configuration for renaming methods
- configuration for renaming classes
- generic way of callback binding (you may use regular C functions)
- automatic subclassing (you may register types in C or use Vala for subclassing)
- API generation for GLib types that are not GObject-based/non-GObject records
- wrapping or conversion of out-parameters of methods
- conversion of C types that are not
gchar
or GObject-based (you may just use them "as is") - ObjC implementation of GObject type interfaces, protocol translation layer
- ObjC implementation for container types like
GList
,GSList
,GHashTable
andGArray
,GPtrArray
,GByteArray
usingOFArray
orOFDictionary
f.e.
The current state of gir2objc I call "tech preview". I expect it to work, but it's far from being complete or universally usable and I expect it to still have many bugs. I don't make any promises regarding its development progress as I develop it only as I need it for my (currently only) app contacts2phone.
See milestones for the further release plan.
You're welcome! Without your help this project isn't going to advance. Create a Codeberg account and submit a pull request. Contact me before submitting a bigger one. Agree to publishing under the terms of GPL 3.0.
Join Matrix room #objfw:nil.im
at any time to discuss issues and questions.
You may run gir2objc
as installed binary (f.e. within a flatpak app) or locally. it expects Config
, Resources
and LibrarySourceAdditions
directories with the corresponding files to work with. It will look for these either in the configured data path (f.e. /usr/share/gir2objc/
) or .
if the configured path is empty. You may tweak the app configuration and behaviour using the global_conf.json
and library_conf.json
files.
Run it like so:
gir2objc </path/to/file.gir>
f.e.
gir2objc /usr/share/gir-1.0/Gtk-4.0.gir
This will generate the library definition for GTK4 into the output dir specified by the config file. The output will include all the library dependencies specified by Gtk-4.0.gir
.
The generator is going to lookup these dependencies recursively at the path of the gir file specified as argument. You may exclude library and class dependencies of each library by modifying global_conf.json
and library_conf.json
.
- gcc or clang, make, autoconf
- ObjFW
- pkg-config
- ObjFW
- The GIR files for the library to generate a wrapper for - and all of its depending GIR files. This will be enough for generation of the wrapper source files. You are going to need all library files (shared library, headers, pkg-config description) and the files of the dependending libraries required for your library at build time (only).
- For GLib-2.0 using Debian/Ubuntu this is at least libgirepository1.0-dev including the GIR file for GIO.
- For building a generated library you need OGObject.
Build a generated library calling from its root dir:
./autogen.sh
./configure
make
Use make install
for installing. For further options to configure build and installation see ./configure --help
You may use the GIR files and libraries provided by your Linux distribution. F.e. for Debian Unstable and GTK 4 use apt install libgtk-4-dev
.
If you don't use a rolling Linux distribution, the GIR packages and its library sets may be out of date and lack features required by this generator. It then may be more appropriate to use some more recent library releases. If you want to get the current libraries (read: daily builds of the GNOME SDK) you may use flatpak (see below).
As noted by the GTK bindings for Rust project it may be helpful to consult the GIR format reference or the XML schema.
chmod +x autogen.sh && ./autogen.sh && ./configure && make
# Add the GNOME Nightly repo
flatpak remote-add --if-not-exists gnome-nightly https://nightly.gnome.org/gnome-nightly.flatpakrepo
# Install SDK and LLVM extension
flatpak install org.gnome.Sdk//master -y --noninteractive
flatpak install org.freedesktop.Sdk.Extension.llvm17 -y --noninteractive
# Build binary and install it in its sandbox
flatpak-builder build-dir --force-clean org.codeberg.objgtk.gir2objc.yml --user --install
# Run the app: This will use the most current GIR files from the SDK and output ObjGTK4 to your local working directory:
flatpak run org.codeberg.ObjGTK.gir2objc /usr/share/gir-1.0/Gtk-4.0.gir
gir2objc is free software. Its source files Tyler Burton originally released under GNU LGPL 2.1 or later. This licensing was kept for the files existing and for the directory LibrarySourceAdditions, which is meant to be part of the generated libraries and is NOT part of the generator.
In consent with Tyler Burton the generator itself is released under GNU GPL 3.0 or later.
Regarding GTK3 (and 4 or any other library wrapper) the generator is meant to generate wrapper source files which may be distributed under LGPL 2.1 or later.
The generator does the following currently:
- Using
XMLReader
it parses a GIR file (.gir) into object instances of the GIR classes (see directorysrc/GIR
) (source models) Gir2Objc
then maps the information of the GIR models into the models prefixed withOGTK
(see directorysrc/Generator
) (target models, "information objects"). Please note that these models still hold API/class informationen using C names and types as used by the Glib/GObject libraries. These models provide methods to transform their Glib ("c") data/names/types into Objective-C classes/names/types.- It does the same for further libraries iterating recursively through all the libraries specified as dependencies by the GIR file given.
- When all library and class definitions are held in memory necessary to resolve class dependencies correctly using
OGTKMapper
, thenOGTKLibraryWriter
is called to first invokeOGTKClassWriter
. OGTKClassWriter
is going to write out the Objective-C class definitions (header and source files). It does so by resolving GObject types to Objective-C/OGTK types (swapping them) using the class mappings and definitions hold in multipleOFDictionary
s byOGTKMapper
. It wraps GObject C functions calls with Objective-C method calls/message sends.- When all class files are written, additional source files, written manually, that may be provided through a directory within the directory named
LibrarySourceAdditions
are added to theOutput
directory (the generated library). Please note the classes located in the directory namedLibrarySourceAdditions
are not part of the generator itself. You may add your own code by creating new directories which naming convention needs to meet that of the corresponding gir file.
You will find the main business logic preparing data structures in Gir2Objc.m
and Generator/OGTKMapper.m
as Gir2Objc
calls OGTKMapper
for multiple loops through all the parsed (Gobj) class/API information to complete dependency information (naming of parent classes) and the dependency graph (parent classes, depending classes). This is necessary to correctly insert #import
and @class
statements when generating the ObjC class definitions without getting stuck in a circular dependency loop.
For the actual generation and composition of the source files see Generator/OGTKLibraryWriter.m
and Generator/OGTKClassWriter.m
.