Thursday, 24 October 2013

Every time you use CONFIG+=ordered, a kitten dies.

QMake users: public service announcement. If you use CONFIG+=ordered, please stop right now. If you don't, I'll hunt you down. I promise to god I will.

There is simply no reason to use this, ever. There's two reasons this might be in your project file:
  1. you have no idea what you are doing, and you copied it from somewhere else
  2. you have a target that needs to be built after another target, and you don't know any better
If you fit into category 1, then I hope you're turning red right now, because by using CONFIG+=ordered, you're effectively screwing over multicore builds of your code. See a very nice case of this here.

If you fit into category 2, then you're doing it wrong. You should specify dependencies between your targets properly like this:

TEMPLATE = subdirs
SUBDIRS = src plugins tests docs
plugins.depends = src
tests.depends = src plugins

And then you'll have docs built whenever the build tool feels like it, and the rest built when their dependencies are built.

If you have subdirectories involved in this, then you need an extra level of indirection in your project, but it's still not rocket science:

TEMPLATE = subdirs
src_lib.subdir = src/lib
src_lib.target = sub-src-lib

src_plugins.subdir = src/plugins
src_plugins.target = sub-plugins
src_plugins.depends = sub-src-lib

SUBDIRS = src_lib src_plugins

For those of you wondering why I sound frustrated about this, I've fixed so many instances of this by now that it's just getting old and tired, frankly. And I still keep running into more. That's countless minutes of wasted build time, all because of laziness boiling down to a single line. Please fix it.

Labels: , , , , ,

Monday, 17 January 2011

Qt: users of qmake, rejoice!

Those of you who have used qmake to build projects for any length of time on Linux will have probably come across the PKGCONFIG feature by now.

For those of you who haven't, here's a quick recap:
CONFIG += link_pkgconfig # enable the PKGCONFIG feature
PKGCONFIG += glib-2.0 # link against glib-2.0
While this looks simple, it has two small problems which aren't all that fun.

Firstly, it had what was really quite easily arguably a bug in that it didn't halt the qmake process if a requested package didn't exist. It would happily tell you it didn't exist, and then continue as if nothing had gone wrong, a very annoying problem in large projects:
$ cat test.pro
CONFIG += link_pkgconfig
PKGCONFIG += foobar

$ qmake test.pro:
Package foobar was not found in the pkg-config search path.
Perhaps you should add the directory containing `foobar.pc'
to the PKG_CONFIG_PATH environment variable
No package 'foobar' found

$ echo $?
0

Secondly, it wasn't possible to (easily) check for optional dependencies and enable/disable functionality depending on the result of that check.

This has now changed! Thanks to Oswald for merging merge request 1022 into Qt, PKGCONFIG will, in the future, stop on error, and (even more fun) - we can now use the shiny new qmake packagesExist() test function to detect whether a library is installed:
CONFIG += link_pkgconfig

packagesExist(glib-2.0) {
    DEFINES += HAS_GLIB
    PKGCONFIG += glib-2.0
}

// and in the code:
#ifdef HAS_GLIB
    // use glib here
#endif
Much thanks to Marco for prompting me to finally try fix this (I've eternally been annoyed by it, but someone else being frustrated by it made me leap into action), as well as to Oswald, Marius and Arvid for their review and comments during writing, and finally to Murray and Mathias for respectively reporting and trying to patch the first issue in this post, a fact I only became aware of *after* finishing my patch. Great minds think alike, it seems!

Labels: , , , , , ,