Pidgin3 Development Scripts


Developing Pidgin 3 can be quite complicated and error prone. Compilation and installation takes a long time and even running an additional instance can be a painful as there are currently two command line arguments that need to be set to make it work.

To make all of this work we use a number of scripts. In fact you may even have seen some of them in use on grim’s stream. But there’s one more piece to all of this and that is the installation prefix.


All projects that use autotools, cmake, meson, qmake, etc have what we call an installation prefix. It’s what tells the build system where to install the software. By default this is typically /usr/local which means your executables will end up in /usr/local/bin, your libraries in /usr/local/lib and so on.

Using the default is usually fine if you’re just running the software, but while developing the need might arise for you to delete everything that’s been installed. While all of these build systems include an uninstall target, there are times when you’ll update your local copy and not realize that installed files have been removed and they end up polluting your install prefix and can cause bugs that are very difficult to debug because there are files that are there that you’re not expecting.

To avoid this or having to run the uninstall target before every update we make it easy to delete everything by using a custom prefix. You’re free to use whatever prefix you like, but grim uses ~/l. The l is just an abbreviation of local and is less likely to be confused with ~/.local which is something completely different.

Using a custom prefix also makes it very easy to make sure we’re always building our subprojects of GPlugin, libgnt, and Talkatu. This is important because at the current stage of development these are being updated directly for Pidgin 3 and vice versa. This works because meson doesn’t add the prefix to the PKG_CONFIG_PATH environment variable so pkg-config is unable to find the installed copies of our subprojects and thus always builds them.

To set the prefix we pass it as an argument to meson during initial configuration via meson --prefix=~/l build or after the fact using meson configure --prefix=~/l from an existing build directory.


Now that the prefix is setup we can start talking about the main developer scripts. They are dev-log-grep, dev-pidgin, local-pidgin, and dev-pidgin-glade.

  • dev-log-grep helps sort through the compiler output as there are currently many deprecation warnings that we’re slowing churning through.
  • dev-pidgin and local-pidgin are used to run Pidgin 3 from a build directory and a local installation respectively.
  • dev-pidgin-glade is used to create and edit our user interface templates in Glade.

These scripts need to be available on your PATH. Typically people put these in ~/bin or ~/.local/bin and will need to be added to your PATH environment variable via your shell’s initialization which is outside of the scope of this document.


dev-log-grep is a simple script that uses grep to ignore the deprecation warnings from the compiler output. However, it was built to run after the build. This works best when doing a clean build, that is running ninja clean before running ninja but that isn’t necessary. However, you need to slightly modify your ninja command to make this work. The ninja command you need to use is ninja |& tee log. This will run the build like normal, then you can use dev-log-grep to see the warnings that we aren’t ignoring.

The contents of dev-log-grep can be found below.


grep -i warning log | grep -vi deprec | grep -vi "failed to parse" | grep -vi "bare structure or union" | grep -vi "callbacks cannot be return values" | grep -v "Unresolved type"


The dev-pidgin script is used to run Pidgin from your build directory. This is useful if you’re just testing something in libpurple or Pidgin directly, but if you’re working on plugins you’ll need to use local-pidgin which is explained later.

The contents of dev-pidgin are below. You can tweak them as necessary, but we’ll walk through what it does.

#!/bin/sh -e

TOOL="gdb --args"
#TOOL="valgrind --leak-check=full --suppressions=/usr/share/glib-2.0/valgrind/glib.supp --suppressions=/usr/share/gtk-3.0/valgrind/gtk.supp"

export LD_LIBRARY_PATH=libpurple/:pidgin/

${TOOL} pidgin/pidgin3 \ \
	--config ~/.pidgin3-dev \
	--debug \

The first line sets up our shell interpreter and tells it to exit on the first error it encounters. Lines 3 and 4 are an optional prefix we can use to run Pidgin 3 in either gdb or valgrind.

We use gdb for debugging and valgrind for finding memory leaks and other memory errors. The paths for the valgrind suppressions are distribution dependent and may not be available on distributions. The ones listed here are from a Debian system. Only one of these can be used at a time so just make sure to uncomment the one you would like to use.

Next we update LD_LIBRARY_PATH to tell the dynamic linker where to find the libraries that are part of our build. If you’re on macOS you’ll need to set DYLIB_LIBRARY_PATH instead.

Finally we have the command that will actually run Pidgin 3. It uses the prefix variable if defined, then specifies the pidgin3 executable to run. The --gapplication-app-id argument is used to uniquely identify this instance of Pidgin 3. This identifier is used to allow only one instance matching this identifier to run at a time.

The --config argument specifies where Pidgin 3 will store its configuration data. Next the --debug argument tells Pidgin to output all of the debug statements to the console. Finally ${@} will pass any arguments that were passed to dev-pidgin to be passed to the pidgin3 executable.


local-pidgin is nearly identical to dev-pidgin so we won’t go into much depth as most of it is already covered above. The point of local-pidgin is to be able to run pidgin3 from an installed prefix that is not /usr or /usr/local. In the example below we have Pidgin 3 installed with a prefix of ~/l like we discussed earlier.

#!/bin/sh -e

TOOL="gdb --args"
#TOOL="valgrind --leak-check=full --suppressions=/usr/share/glib-2.0/valgrind/glib.supp --suppressions=/usr/share/gtk-3.0/valgrind/gtk.supp"

export LD_LIBRARY_PATH=~/l/lib/x86_64-linux-gnu

${TOOL} ~/l/bin/pidgin3 \
	--gapplication-app-id=im.pidgin.local \
	--config ~/.pidgin3-local \
	--debug \

Since this is for the installed version of Pidgin 3 we just need to point to everything for that installation. That means updating LD_LIBARY_PATH, or DYLIB_LIBRARY_PATH if you’re on macOS, as well as changing the path to the pidgin3 executable.

Finally we set a separate application id as well as configuration directory. These do not need to be different than the ones from dev-pidgin but if you want to run both instances for testing things this makes it easier.


dev-pidgin-glade is the last of our development scripts. Its purpose is to allow developers to create and modify glade templates for Pidgin 3. This works by the use of a Glade catalog for the Pidgin widgets. However, in this intro we’re just going to cover how to edit templates for Pidgin 3 but not adding new widgets to the catalog.

This script is designed to be run from a Pidgin 3 build directory after Pidgin 3 has been built. This is necessary so that Glade can actually load the required libraries and catalogs.


export LD_LIBRARY_PATH=pidgin/:libpurple/:subprojects/talkatu/talkatu:subprojects/gplugin/gplugin-gtk/

export GLADE_CATALOG_SEARCH_PATH=pidgin/glade:subprojects/gplugin/gplugin-gtk:subprojects/talkatu/talkatu

glade ${@}

Like the other script here, this one sets up LD_LIBRARY_PATH to point to the libraries in the build directory. Remember if you’re on macOS this needs to be DYLIB_LIBRARY_PATH.

Next, we tell Glade where to find the catalogs for Pidgin, GPluginGtk, and Talkatu all of which we are building and depend on.

With everything set up we can finally run Glade passing along any arguments that were passed to our script.

We hope you all found this information useful and we will keep this post updated in the future.

Looking to reach us via XMPP? Check out the new PidginChat service!