A brief introduction to the Xfce Developer Tools
The Xfce Developer Tools -
xfce4-dev-tools for short - provide an easy way to handle the setup and maintaince of a projects build framework. They currently consist of a bunch of M4 macros for commonly used checks and the
xdt-autogen script, which examines the projects
configure.in file(s) and calls the appropriate autotools in the correct order.
As the name suggests, the Xfce Developer Tools are mainly useful for application developers to maintain their build environment. But users will also be required to install them if they plan to build software straight from CVS or SVN checkouts.
Preparing the project
In this section I will describe how to use the developer tools with your project. We will therefore examine a sample project and discuss the various steps. Our sample project will contain only a single binary, which does nothing useful. The project itself will be named
sample, and will depend on
libxfcegui4 and can optionally use D-BUS (this is only to demonstrate the usage of some of the M4 macros). And our project will be translatable to other languages.
We start off with the
Makefile.am's and the source code. First, we create the projects directory layout:
mkdir sample mkdir sample/po mkdir sample/sample
sample/main.c source file:
main (int argc, char **argv)
xfce_textdomain (GETTEXT_PACKAGE, PACKAGE_LOCALE_DIR, "UTF-8");
g_print (_("Hello World!\n"));
As you can see, we conditionally include
dbus/dbus.h only if the
HAVE_DBUS preprocessor macro is defined. The check for D-BUS is made in the
configure.ac file, which is discussed below. Besides that, the only thing we do here is to print the string
"Hello World!" in a translatable manner, after setting up the proper textdomain for gettext.
We continue with the
sample/Makefile.am, which contains instructions about how to compile the
INCLUDES = \
bin_PROGRAMS = \
sample_SOURCES = \
sample_CFLAGS = \
sample_LDFLAGS = \
$(localedir) make variable is set by the
XDT_I18N() macro and will point to the location where the translations are installed (e.g.
$(LIBXFCEGUI4_LIBS) variables are set by the appropriate calls to
XDT_CHECK_PACKAGE(), which will be discussed below. Note that
$(DBUS_LIBS) will be empty if D-BUS was not found or disabled by the user.
We also need to define
DBUS_API_SUBJECT_TO_CHANGE because the D-BUS API is not yet frozen, but that's an unimportant detail in the context of this article.
Furthermore we will also need a toplevel
Makefile.am, which should look like this:
SUBDIRS = \
AUTOMAKE_OPTIONS = \
AUTOMAKE_OPTIONS variable is used by
automake to enable or disable special behaviour. In this case, the
automake that we need version 1.8 or better. And the
dist-bzip2 option tells
automake to generate a
dist target, which will not only create the gzipped source tarball, but also a bzip2 compressed source tarball.
Now we are done with the
Makefile.am's. The next step is to take care of the i18n setup. Therefore we need to create an empty
po/ChangeLog file (the
po/Makefile.in.in generated by
glib-gettextize requires this file)
and afterwards create the
po/POTFILES.in file, which lists all source files (and sometimes other files like
.xml files as well) that contain translatable strings. In this case only the
sample/main.c file contains a translatable string, so the file looks like this:
Note that all paths in
po/POTFILES.in must be relative to the projects toplevel directory. One last step before we go on to the
configure.ac file is to create four required files for GNU projects:
touch AUTHORS ChangeLog NEWS README
You should of course add content to these files later on, but for now, we want to concentrate on the important facts, the contents of
dnl Version information
dnl Initialize autoconf
AC_COPYRIGHT([Copyright (c) 2005
Benedikt Meurer <email@example.com>])
AC_INIT([sample], [sample_version()], [firstname.lastname@example.org])
dnl Initialize automake
dnl check for basic programs
dnl Check for i18n support
dnl Check for required packages
XDT_CHECK_PACKAGE([LIBXFCEGUI4], [libxfcegui4-1.0], [4.2.0])
dnl Check for optional packages
XDT_CHECK_OPTIONAL_PACKAGE([DBUS], [dbus-1], [0.22], [dbus], [D-BUS support])
You should be familar with most of the above, therefore we will only discuss the
XDT_CHECK_OPTIONAL_PACKAGE() macros here. If you are not familar with the basic autoconf and automake macros, you should have a look at the GNU manuals.
XDT_I18N(LINGUAS [, PACKAGE])
This macro takes care of setting up everything for i18n support.
PACKAGE isn't specified, it defaults to the package tarname; see the description of
AC_INIT() for an explanation of what makes up the package tarname. Normally, you don't need to specify
PACKAGE, but you can stick with the default.
XDT_CHECK_PACKAGE(VARNAME, PACKAGE, VERSION [, ACTION-IF [, ACTION-IF-NOT]])
VERSION is installed on the target system, using the
pkg-config utility. If the dependency is met,
VARNAME_REQUIRED_VERSION will be set and marked for substition. For example, if you specify
GTK for the
VARNAME parameter, the variables
GTK_REQUIRED_VERSION will be set appropriately and substituted.
VARNAME_REQUIRED_VERSION will be set to the value of
VERSION. This is mostly useful to automatically place the correct version information into the RPM
In addition, if the dependency is met,
ACTION-IF will be executed if given.
If the package check fails,
ACTION-IF-NOT will be executed. If this parameter isn't specified, a diagnostic message will be printed and the configure script will be terminated with exit code 1.
XDT_CHECK_OPTIONAL_PACKAGE(VARNAME, PACKAGE, VERSION, OPTIONNAME, HELPSTRING [, DEFAULT])
Checks for an optional dependency on
DEFAULT can be
"no" (defaults to
"yes" if not specified) and controls whether configure should check this dependency by default, or only if the user explicitly enables it using a command line switch.
This macro automatically adds a commandline switch based on the
OPTIONNAME parameter (
--disable-optionname), which allows the user to explicitly control whether this optional dependency should be enabled or not. The
HELPSTRING parameter gives a brief(!) description about this dependency.
If the user chose to enable this dependency and the required package was found, this macro defines the variable
VARNAME_FOUND and sets it to the string
"yes", in addition to the 4 variables set by
VARNAME_FOUND will not be marked for substition. Furthermore, a C preprocessor define
HAVE_VARNAME will be placed in
config.h (or added to the cc command line, depending on your
configure.ac content) and set to 1.
Now that everything is in place we are ready for the first run. Therefore, go to the toplevel directory of the project and execute the
command that comes with the developer tools. This will run all the required autotools (in our case these are
autoconf), and afterwards run the generated
The next thing to do is to generate all language files specified with the
XDT_I18N() macro (we've only specified
de in our
configure.ac). Therefore execute the following commands:
cd po make sample.pot cp sample.pot de.po
Now if you check
po/de.po, it will contain exactly one translatable string, the one from
That's it, now you can simply run
in the projects toplevel directory in order to build your project for the first time. Congratulations, you've successfully completed the build framework setup.
The source code for the sample project is available here.
For more details on the internal workings and the other available macros, check the M4 files in the
m4macros/ subdirectory of the Xfce Developer Tools distribution.