Vala Autotool Tricks

If you have a project that uses Vala and autotools, you are probably using automake 1.11’s native support for the language.

Overall, automake’s support is great. But there are a few oddities that I’ve worked around and thought I’d share here.

Declaring a preferred valac version

Let’s say your project expects valac-0.14. But sometimes people have more than one valac installed, and valac-0.14 may not be their default valac compiler. The AM_PROG_VALAC macro only looks for ‘valac’ in PATH, so you’ll end up with whatever default compiler the user has.

Instead, create an acinclude.m4 file in your project directory. Copy the AM_PROG_VALAC macro from /usr/share/aclocal-1.11/vala.m4 into it. Then:

  1. Change the name to something like MY_PROG_VALAC
  2. Change the AC_PATH_PROG line to something like:
    AC_PATH_PROGS([VALAC], [valac-0.14 valac], [])
  3. Change the AM_PROG_VALAC call in configure.ac to be MY_PROG_VALAC instead

Now configure will first look for the ‘valac-0.14’ executable and then fallback to plain old ‘valac’.

Stop shipping C code

For a long time, I shipped the valac-generated C code with my release tarballs because I did not want distributors to have to deal with valac churn. But nowadays, especially with valac’s six month release cycle, things are calmer.

Not shipping the C code makes tarballs smaller (over 20% in my case), makes it easier for distros to grab upstream patches (they don’t have to create a C patch from your Vala patch), lets you use Vala conditionals (more about that below), and means you’re not shipping something different than you yourself are using.

This only requires a simple change. In each source directory that contains Vala code, add the following bits to its Makefile.am (for the purposes of this example, your Makefile.am is creating the program foo):

  1. Separate out all your .vala code files into a separate variable called foo_VALASOURCES. If you want, you can then use this variable in your foo_SOURCES variable, so you don’t have to specify them twice.
  2. Add the following dist-hook:
    dist-hook:
    	cd $(distdir) && \
    	rm $(foo_VALASOURCES:.vala=.c) foo_vala.stamp

This will delete the generated C code and stamp file when creating a dist tarball.

Use Vala conditionals

One problem with shipping the generated C code is that you can’t use #ifdefs in your code. This is because Vala does not have a version of #ifdef that will “fall through” to the C code. Whether a conditional block of code gets used or not is always decided at valac compilation time.

And since your tarball consumers were compiling the C code, you couldn’t use Vala conditionals. To have an optional project dependency, you had to write little C wrapper functions that did use real C #ifdefs and then call them from Vala. Which is a pain.

But now that you’re shipping straight Vala code, all compilers of your program can now have Vala conditionals decided at compilation time.

Let’s say you have an optional dependency on libunity:

  1. In your configure.ac, find the block of code that deals with having successfully detected libunity and add the following line:
    AC_SUBST(UNITY_VALAFLAGS, ["--pkg unity -D HAVE_UNITY"])
  2. In your Makefile.am files, add $(UNITY_VALAFLAGS) to AM_VALAFLAGS
  3. In your Makefile.am files, add a new dependency to each of your stamp files:
    foo_vala.stamp: $(top_srcdir)/config.h
  4. In your Vala code itself, you can now surround your libunity-using code blocks with #ifs:
    #if HAVE_UNITY
    ...
    #endif

The first step declares the HAVE_UNITY symbol if we’re using libunity. If we’re not, that line won’t ever be reached and UNITY_VALAFLAGS will be empty. The only other interesting bit is step three, which ensures that when ./configure is re-run, valac will also be re-run to pick up any new symbol definitions.

Backups and Distro Upgrading

tl;dr; I don’t recommend using Déjà Dup to hold your data when you upgrade distros (e.g. from Ubuntu 11.04 to 11.10) without understanding the risks.

I’m the maintainer of the Déjà Dup backup tool that will be included by default in Ubuntu 11.10. So I’m generally biased in its favor. But I am also a cautious person.

My concern stems from the fact that Déjà Dup uses an opaque backup format [1]. Which means that it does not store your data in plain files that you can just copy back into place with the file manager. You’ll need to use Déjà Dup again to restore them [2]. Which is fine if Déjà Dup is working correctly, as it should.

But just from a risk management perspective, I always recommend that people try to have at least one copy of their data in “plain files” format at all times.

So if you back up with Déjà Dup, then wipe your disk to put Ubuntu 11.10 on there, you’re temporarily going down to zero “plain file” copies of your data. And if anything should go wrong with Déjà Dup, you’ll be very sad.

Here are a few recommended ways to upgrade:

  • Use the Ubuntu CD’s built-in upgrade support. It will leave your personal files alone, but upgrade the rest of the system.
  • Use the Update Manager to upgrade your machine. Again, this will leave all your personal files in place.
  • Copy your files to an external hard drive with your file manager and copy them back after install.

In my mind, a backup system’s primary use case is disaster recovery, where going down to zero “plain file” copies of your data is unintentional and an acceptable risk. Intentionally reducing yourself to zero copies seems unnecessary.

Hopefully, all this caution is overblown. I just want people to be aware of the risks.

[1] Déjà Dup uses an opaque format to support a feature set that just can’t be done with plain files:

  • Encryption
  • Compression
  • Incremental backups
  • Assuming little about the backup location (allowing cloud backups)
  • Supporting file permissions, even when backing up to locations that don’t

[2] There are technically ways to recover without going through the Déjà Dup interface. They just aren’t very user-friendly.

OnlyShowIn Unity

tl;dr; version: Add Unity to your OnlyShowIn keys.

This is just a PSA that I’ve been doing work in Ubuntu to support Unity’s addition to the set of registered XDG environments.

Which means that in your desktop file, you can now say OnlyShowIn=Unity; to have an application only show up or only autostart in Unity instead of KDE, GNOME, etc. (Or alternatively, use NotShowIn=Unity;)

By and large, Unity uses the same apps and services that GNOME does. So if you currently have an application that does OnlyShowIn=GNOME;, there’s a very good chance it should now be OnlyShowIn=GNOME;Unity;. You might also want to re-evaluate whether you even need OnlyShowIn.

I’ve filed a bunch of bugs against various GNOME apps and patched them in Ubuntu. But I’ve only focused on apps that Ubuntu installs by default.

GtkGrid is Great

One under-the-radar change in GTK+ 3.0 was the addition of GtkGrid, which can replace GtkBox and GtkTable. There are two major reasons it is great:

  1. Better support for the new height-for-width layout engine. I’ve had several layout and spacing issues with labels and GtkTable in 3.0, but converting to GtkGrid fixed them. So if you’re having odd spacing issues, try a Grid.
  2. GtkGrid finally adds the feature that rows or columns with hidden contents also automatically hide their spacing. So if you’re making use of dynamic layouts that add and hide rows, you don’t have to jump through hoops to making your spacing perfect.