GPlugin
Tags: opensource, development, plugin, repost
Published: 2023-06-16 14:00:00

> This article was originally posted on [Patreon](https://www.patreon.com/posts/gplugin-80961449) and has been brought over here to get all of the [Pidgin](https://pidgin.im) Development/History posts into one single place.

As you may or may not be aware, Pidgin 3 has a "brand new" plugin library named GPlugin. It's not exactly brand new as I actually started it back in 2011, but Pidgin 3 is the first project to really use it.

Over the years the plugin system in libpurple has met most of our needs but there were some new developments in generating language bindings that made me pull the trigger on writing a new library.

For starters, if you don't know, I got my start in Gaim/Pidgin by writing plugins, lots of plugins. So many plugins that we created a plugin pack so we only had one thing to distribute. Obviously, I really like plugins.

Back when I was still working on the successor to Guifications 2 which was supposed to be its own service, similar to libnotify on unix desktops, I wanted plugins for all the things. I started writing this into the core library of that platform but decided it would better serve everyone, including myself, so I split it out.

Originally I called it gidbits which was supposed to be an alliteration of mumbled "good bits", but I quickly renamed it to GPlugin because it's heavily GObject based, or maybe it's because I go by Grim.. The world may never know...

Anyways, GPlugin was created out of the desire to replicate what we did with plugins in Purple 2 and earlier. That is, it should allow loading plugins in other languages and let them all work at the same time.

Before starting GPlugin I, of course, looked for anything else that already existed. I came across [libpeas](https://wiki.gnome.org/Projects/Libpeas) but there are some philosophical issues there. Namely that libpeas only allows one plugin language outside of native plugins. So this wasn't going to allow us to reach our goals and thus GPlugin was created.

As mentioned earlier, GPlugin makes heavy use of the GObject system. This is done for a number of reasons, but the most important one is so that we have a consistent reference counted and type checked API.

We also needed this because as Purple 3 also turned into a GObject based library, we needed a way to properly handle the dynamically created GObject subclasses in plugins. In Purple 2 we used to work around this by registering the types as static and then making the plugins unloadable. This meant you couldn't ever actually disable the plugin unless you modified prefs.xml which sucks.

GPlugin has a whole bunch of API to combat issues like this, but by default it gives you the GTypeModule for your plugin so you can just create dynamic types properly. There's a lot more to be said here, but it'd require getting a lot deeper into the GObject type system which is out of the scope of this blog post.

The real power of GPlugin actually doesn't come from GPlugin at all. It comes from [GObject Introspection](https://gi.readthedocs.io/en/latest/). GObject Introspection works similar to documentation tools in that it scans your source code, but instead of outputting documentation it creates XML and binary representations of your API. With those files, you can now easily use your GObject based library via any language that has GObject Introspection bindings built for it.

This is amazing because before GObject Introspection, you used to have to hand craft bindings for any other languages you wanted to support. You could try your luck with generator tools like [SWIG](https://www.swig.org/), but I never had much luck there. But now with GObject Introspection your library is just usable from whatever.

However, to make this work inside of GPlugin and therefore Purple 3, GPlugin needs to be able to load that language as well. For native languages this is easy, you can just use the Native Plugin loader. You can see an example of how to build a C plugin [here](https://docs.imfreedom.org/gplugin/native-plugins.html) and a [Vala](https://vala.dev/) plugin [here](https://docs.imfreedom.org/gplugin/vala.html). You'll notice that the API is very similar and that is very intentional.

GPlugin also provides loaders for [Lua](https://www.lua.org/) and [Python 3](https://www.python.org/) as well. These loaders very simply embed the language interpreters into GPlugin and then evaluate your plugins that are using GObject Introspection to talk to the GPlugin C API directly with zero manual bindings. You can find example plugins for here for [Lua](https://docs.imfreedom.org/gplugin/lua.html) and [Python 3](https://docs.imfreedom.org/gplugin/python3.html).

GPlugin also provides GTK Widgets to make it easier to integrate into your own GTK applications, but if you're just looking to use GPlugin in your application, you can find a simple example right over [here](https://docs.imfreedom.org/gplugin/embedding.html)!

I've put a lot of time and effort into GPlugin and I'm looking forward to everyone getting to use it in the future once we finally get Pidgin 3 out the door!

I hope you're enjoying these posts! Remember they go live for patrons at 9AM CST on Mondays and go public at 12AM CST on Thursdays! If you'd like to support my work, you can join find a list of ways to do so [here](https://imfreedom.org/donate/#gary-kramlich).