Calamares is a distro-, desktop- and toolkit-independent installer for Linux systems. It it intended to be the thing that gets your CD installed onto the hard drive of the target system. The Dutch term voortschrijdend inzicht is applicable here, too, as CD’s have been replaced by ISO images or USB sticks and hard drives are now (virtualised) SSDs instead. Today, though, I’m going to look at the packaging of Calamares – what distro’s do to get a Calamares executable that can be put on that CD.

In this post I’m going to pick apart a PKGBUILD script – that’s for Arch and derivatives. It is not intended to pick on that particular script: the script is there to get the effect that the distro wants, and if it solves their problem, it is Good Enough™.

Packaging software is an activity that is as old as Linux distro’s. Older, even, but the idea is that it is the distro that picks some sources, selects options and compile flags and bundles things up really took off with the “Cambrian explosion” of packaging formats. On the FreeBSD front, there is the ports tree which is 40000 Makefiles, and Arch has PKGBUILD, among others in the Arch Linux user repository. Other distro’s have similar collections of build instructions.

The thinking in packaging is swinging towards developer-led packaging in AppImage or SnapCraft or FlatPak. I’m still not sure what I think of that in general, but for Calamares it really doesn’t make sense: Calamares is not an end-user application, it’s intended to be used once in a pretty specific situation and then discarded.

So Calamares is pretty traditional, shipping a source tarball, and you’re expected to run cmake; make; make install to to the things. As time goes by, voortschrijdend inzicht applies (the realisation that things could be better) and conveniences are added to the CMake files, and knobs added or tuned.

I realised that I did not advertise that kind of improvements in the release notes for Calamares, when I looked at a PKGBUILD file for it.

Getting Version Information

This particular PKGBUILD is intended to consume Calamares git-nightly, so it starts from a git checkout. For the safe and correct labeling of the package, it wants a full version, not just the major.minor.patch version.

pkgver() {
	cd ${srcdir}/calamares
	_ver="$(cat CMakeLists.txt | grep -m3 -e "  VERSION" | grep -o "[[:digit:]]*" | xargs | sed s'/ /./g')"
	_git=".r$(git rev-list --count HEAD).$(git rev-parse --short HEAD)"
	printf '%s%s' "${_ver}" "${_git}"
	sed -i -e "s|\${CALAMARES_VERSION_MAJOR}.\${CALAMARES_VERSION_MINOR}.\${CALAMARES_VERSION_PATCH}|${_ver}${_git}|g" CMakeLists.txt
	sed -i -e "s|CALAMARES_VERSION_RC 1|CALAMARES_VERSION_RC 0|g" CMakeLists.txt
}

This extracts the M.m.p version number from CMakeLists.txt (based on the version being listed in the project() call in a specific way), appends a git hash to it, then goes back and edits that version in to the CMakeLists.txt. While there, set RC to 0 (so behave like a release).

Calamares itself has had this information for a long time: there is a CalamaresVersion.h and a CalamaresVersionX.h with the short-form and the long-form (including git revision and date) version information. There was even a special-case (make) target that does nothing but print out the version!

So here’s a clear case of communications failure: I didn’t advertise the availability of the version information, and the distro did not clearly ask for it upstream. So we ended up building similar solutions independently, rather than doing it once-and-for-all.

Changes Made

As I mentioned in my post about CMake script mode, I can use CMake itself to print versioning information for the distro. Once I had done that, I realised that in doing so, I broke their build!

The PKGBUILD depends on a particular structure of the CMakeLists.txt file. I removed that structure, so it’s now broken. Even though I built a convenient means to get the same information, and so “fixed” the underlying problem (getting versioning information), it’s still no good for this particular distro.

The change in question has been deferred to Calamares 3.3, which is full of breaking changes (dependencies, requirements, configuration changes) and is going to need a big “heads up” to distro’s anyway.

Things that I have done in the current Calamares release series, though, include:

  • dropping useless information from the version (“rc1” to show a version is a development version; that’s also obvious from the date and git hash in the version),
  • providing a slightly more compact version string,
  • making calamares --version print the long version string,
  • logging the long version string on startup.

It’s also clear that I need to start advertising “this may have an effect on packaging” in release notes. So after Easter there’s still things to do.