I’m starting the third week of coding on my GSoC 2013 project, a new break timer application for GNOME. I spent the last two weeks working on an odd mix of little things. For the most part, my goal over that time was to make the gnome-break-timer project (previously brainbreak, still brainbreak in most places) nicer to work with. I’m a bit of a sucker for clean code, and, well…
So, to start off, I switched over to Automake from my old build system, which was using BuilDj and Waf. I’m still a big fan of those two, at least philosophically. In practice, Automake just seemed like a good choice because it’s familiar to people, and I really want to maintain a high bus factor for this project. This isn’t the sort of application that I would expect to have a continuous flow of regular contributors, so I think it’s important that someone can jump in and figure it out for without too many obstacles.
One interesting puzzle here was doing a convenience library with Automake and Vala. I started using convenience libraries for this project so I could strictly define different parts of the application. The idea is code at one level shouldn’t know anything about code above it, and we can formalize that by actually building these bits of code to separate objects that get linked together later. This also, conveniently, allows us to reuse the code that is common between the settings panel and the break timer daemon without needing to compile it twice. Not a big deal here, but I like it anyway.
I found lots of helpful information about doing convenience libraries with Automake, but Vala posed something of a problem because Automake doesn’t do everything for us with Vala (yet). I need to pass several extra flags to valac, both for the library and for the target that uses the library, and I need to do that without messing up build dependencies. I don’t want to run into cases where the build fails (or, worse, doesn’t fail!) until I run make clean
. (For what it’s worth, the old build system with BuilDj and Waf figured this out wonderfully and generally rebuilt the thing about twice as fast as Automake, but I also hadn’t set up localization or config.h, so I guess that’s kind of moot). I checked out how some projects like Deja Dup were doing convenience libraries, and I came up with a handy reusable pattern:
Makefile.am for the rather unhelpfully named “common” module:
M_CPPFLAGS = $(BRAINBREAK_CFLAGS) \ -include $(CONFIG_HEADER) noinst_LTLIBRARIES = \ libcommon.la libcommon_la_SOURCES = \ NaturalTime.vala \ SessionStatus.vala \ ... libcommon_la_LIBADD = \ $(BRAINBREAK_LIBS) libcommon_la_VALAFLAGS = \ --pkg gio-2.0 \ --library common \ --vapi common.vapi \ -H common.h junk_files = \ $(libcommon_la_SOURCES:.vala=.c) \ libcommon_la_vala.stamp dist-hook: cd $(distdir) && rm -f $(junk_files) CLEANFILES = \ $(junk_files) \ common.vapi \ common.h
Makefile.am for some code that uses that module:
AM_CPPFLAGS = $(BRAINBREAK_CFLAGS) \ -include $(CONFIG_HEADER) \ -I $(top_srcdir)/common SUBDIRS = bin_PROGRAMS = \ brainbreak-settings brainbreak_settings_SOURCES = \ ApplicationPanel.vala \ BreakPanel.vala \ BreakType.vala \ main.vala \ ... brainbreak_settings_VALAFLAGS = \ --pkg gtk+-3.0 \ $(top_srcdir)/common/common.vapi brainbreak_settings_LDADD = \ $(BRAINBREAK_LIBS) \ $(top_srcdir)/common/libcommon.la brainbreak_settings_vala.stamp: \ $(top_srcdir)/common/libcommon_la_vala.stamp junk_files = \ $(brainbreak_settings_SOURCES:.vala=.c) \ brainbreak_settings_vala.stamp dist-hook: cd $(distdir) && rm -f $(junk_files) CLEANFILES = \ $(junk_files)
Of course, I also rewrote a bunch of stuff which had been thrown together a little too hastily. I knew I would need to rewrite a lot of code, but I wanted to get the “rewrite and start over” bug out of my system in the beginning, and I think it worked. Allan Day already came up with some lovely mockups that I could start with, so I used those to guide me in choosing what needed work. As I worked through implementing different bits of his “take a break” UI, I noticed some aspects that would have been quite difficult with the design I had earlier. I squished and pulled things accordingly, giving the UI code a little more power and knowledge, and getting rid of needlessly arcane kinds of “reusable” code. But that’s all a little boring.
I’m really excited for the next bit. I will be working on a beautiful new Break Settings application, complete with GtkHeaderBar and (hopefully) a non-ridiculous time input widget. I’ll post some pictures and a new download soon!
I saw the following posted on the vala list, not sure if can be useful to you:
https://github.com/rastersoft/autovala
I had to work a lot with the auto tools and know little about waf, only that it is similar to SCons. Going from waf to auto* sounds very strange to me…
It is a little strange. The trouble is I wasn’t using Waf directly – I was using it through a nice little tool called BuilDj, which hides a lot of the complexity of Waf (which is already pretty uncomplicated, so as you can imagine it’s really wonderfully easy). Unfortunately, it isn’t really considered finished, so I’m just treating it as a helpful tool for throwing together a prototype. In particular, I never figured out how to set up localization with BuilDj, but there are a lot of resources about setting up localization properly with Autotools.
Meanwhile, it looked like jumping to Waf on its own would be about as much trouble as jumping to Autotools, so I just went with Autotools. It felt like the path of least resistance since so much other stuff in GNOME (including libgd, which I think I’ll need to include as a submodule) uses Autotools. In the end it wasn’t too much trouble. I spent a few hours grumbling about Autotools, but who doesn’t?
When you get that non-ridiculous time input widget. Please let me know. :)