Posts Tagged ‘CMake’

Library versioning

18th November 2015

Do you maintain or contribute to a library, especially a KDE library (other than the Frameworks)? If so, I have a question for you.

First, some background. These days, the norm for libraries is to follow some variation of semantic versioning, where the version number follows the scheme x.y.z (eg: 1.4.3) and it should always be safe to upgrade the library to version with a higher y (minor) component as long as the x (major) component is the same. Qt follows this scheme, for example.

This scheme doesn’t really allow for alpha versions of software, though – the alpha releases for the (x+1) major version can be incompatible with both version x and with the final releases of version (x+1). The Semantic Versioning scheme prescribes using versions like x.y.z-alpha1, but this breaks the nicely numeric scheme we had, and not all tools can cope with that.

KDE Frameworks (and, in the past, kdelibs) approached this by defining some arbitrarily high minor version (typically 90+) to indicate pre-releases for the next major release. So the pre-release Frameworks were numbered like 4.90.1.

So where is all of this going? Well, CMake provides a helpful function to write package version information files that allow find_package() calls to only find compatible versions. So if you use the SameMajorVersion scheme, find_package(Foo 4.3) will find Foo 4.3.0 and Foo 4.5.2, but not Foo 4.2.5 or Foo 5.1.1. However, if project Foo uses the “high minor = next version prerelease” scheme, it will also find Foo 4.90.1, which is not compatible with Foo 4.3.

I wrote a SameMajorVersionWithPreleases scheme that would deal with this for Extra CMake Modules, but never committed it because I wasn’t sure if it would get used (KDE Frameworks doesn’t need it because we put KF5 in the package names). My question is: would your project find this useful? In other words, do you contribute to (or know of) a CMake-based project that uses the “high minor = next version prerelease” scheme I described above? If so, please comment!

CMake Library Tutorial

16th August 2015

Interested in writing or maintaining a KDE Framework? Getting the build system right for a Framework, or indeed any other library, is not trivial. I’ve just finished writing a tutorial to help you do just that, though. It can be found at the CMake tutorials page on TechBase, and guides you through (an idealised version of) the KArchive buildsystem.

Comments, feedback and questions on the tutorial are welcome – here, by email or on the discussion page of the tutorial.

Buildsystem BoF at Akademy

8th July 2015

I’ve just booked a room for Tuesday afternoon at Akademy for a couple of CMake / extra-cmake-modules BoF sessions.

The first part is for people who want support hacking the buildsystem of their own projects. Not sure of the best way to migrate to extra-cmake-modules as part of your shift to KF5? Getting “deprecated” or other CMake warnings you want to resolve? Can you think of something really useful the buildsystem could do in your project, but you don’t know how to do it? Come along, and I (and hopefully others) will be there to give you a hand. Likewise, if you feel comfortable writing stuff in CMake, and you want to help other developers, come along to lend a hand – you don’t need to be an expert!

The second part is for people who want to contribute to extra-cmake-modules. If you have some CMake code in your project you think other projects will find useful, or you have ideas for improvements in the existing modules, come along and pitch in.

New installation variables

13th January 2015

I noticed a while ago that the CMake installation variable names used by KDE projects (defined either in kdelibs or KDEInstallDirs in extra-cmake-modules) are inconsistent with what GNUInstallDirs, for example, uses. The traditional variable names are things like BIN_INSTALL_DIR and CMAKECONFIG_INSTALL_PREFIX, while GNUInstallDirs defines things like CMAKE_INSTALL_BINDIR and CMAKE_INSTALL_DOCDIR.

In an effort to make the installation variables more consistent and compatible with GNUInstallDirs (for the ease of packagers and developers alike), I introduced GNUInstallDirs-style variables to KDEInstallDirs – this included the variables defined by GNUInstallDirs and other ones beginning CMAKE_INSTALL_. These were kept in sync with the old-style variable names.

Both of these styles of variables have namespacing problems: the ones starting CMAKE_ tread on CMake’s namespace (so CMake could potentially define one of those variables that doesn’t appear in GNUInstallDirs to have a different meaning), and the old-style variables are very generic and could conflict with another CMake module. Neither of these are likely to be an issue in reality, but it is good practice to respect namespaces in third-party modules.

KDEInstallDirs now primarily defines variables starting with KDE_INSTALL_ (which corresponds with the module name). The old-style names and all the CMAKE_INSTALL_ names that do not also exist in GNUInstallDirs are deprecated, and can be disabled entirely (see the documentation). It is possible to disable the variables that appear in GNUInstallDirs as well.

This appeared in extra-cmake-modules 1.6.0, but that version had some flaws (for example, it would break if you used both GNUInstallDirs and KDEInstallDirs in the same project, which was a major oversight), so you should use 1.6.1 instead.

There is a script in the kf5 directory of the kde-dev-scripts.git repository to port your CMakeLists.txt files to the new variables: cmakelists_install_vars.pl. Just run it in a directory with a CMakeLists.txt file.

CMake Conditionals

16th May 2014

[edited 17/04/14]

CMake has many wonderful features. However, CMake’s if() command handles variables in a way that can often trip people up. In particular, comparison operators like STREQUAL try to interpret their arguments as variable names, and only treat them as actual strings if there is no matching variable. Combined with the fact that basically any string you can write in a CMake file is a valid variable name, this can lead to some subtle bugs.

This script highlights all the potential pitfalls I could think of. The “FATAL_ERROR” branches are the ones that will not be taken, but many of them are ones you might expect to be taken if you either didn’t have a solid grasp of how if() parses its arguments or if you weren’t aware of what variables had been defined.

(more…)