QMake 'subdirs' template - executing a target?

Rob picture Rob · Jul 22, 2009 · Viewed 8.6k times · Source

I am putting together a build system for my Qt app using a qmake .pro file that uses the 'subdirs' template. This works fine, and allows me to specify the order that each target is built, so dependencies work nicely. However, I have now added a tool to the project that generates a version number (containing the build date, SVN revision, etc,) that is used by the main app - I can build this version tool first but when it is built I want to execute it before any more targets are built (it generates a header file containing the version number that the main app includes.)

For example, my simple qmake file looks like something this:

TEMPLATE = subdirs
CONFIG += ordered
SUBDIRS = version \
          lib \
          tests \
          mainapp

When 'version' is built I want to execute it (passing some arguments on the command-line) before 'lib' is built.

Does anyone know if this is possible? I see that qmake has a 'system' command that can execute apps, but I don't know how I could leverage this.

A related question concerns my unit tests. These live in the 'test' project and use the QTest framework. I want to execute the tests exe before building 'mainapp' and if the tests fail (i.e. the tests exe doesn't return zero) I want to quit the build process.

I realise that qmake is designed to generate makefiles, so I may be wishing for a little too much here but if anyone can give me some pointers it would be very welcome.

Answer

3DH picture 3DH · Jul 22, 2009

I currently use qmake to exec my unit tests automatically for two years - and it works fine.

Have a look here - I made a mini-howto for that:

Qt: Automated Unit Tests with QMAKE

Abridged summary:


Structure

/myproject/
    myproject.h
    myproject.cpp
    main.cpp
    myproject.pro
/myproject/tests/
    MyUnitTest.h
    MyUnitTest.cpp
    main.cpp
    tests.pro

Using QMake to automatically run unit tests on build

The QMake target QMAKE_POST_LINK will run a user defined command after linking.

tests.pri (common file)

TEMPLATE = app
DEPENDPATH += . ../
INCLUDEPATH += . ../
DESTDIR = ./
CONFIG += qtestlib
unix:QMAKE_POST_LINK=./$$TARGET
win32:QMAKE_POST_LINK=$${TARGET}.exe

tests.pro (project-specific file)

TARGET = MyUnitTest
HEADERS += MyUnitTest.h
SOURCES += MyUnitTest.cpp main.cpp
include(tests.pri)

Running multiple unit tests in a single main()

main.cpp

#include "MyUnitTest1.h"
#include "MyUnitTest2.h"

int main(int argc, char** argv) {
    QApplication app(argc, argv);

    int retval(0);
    retval +=QTest::qExec(&MyTest1(), argc, argv);
    retval +=QTest::qExec(&MyTest2(), argc, argv);

    return (retval ? 1 : 0);
}

This runs your tests on each build and aborts if an error is found.

Note

If you get linker errors such as "LNK2005: xxx already defined...", add a new .cpp file for each test class header and move some test method implementations.


You can use exactly that mechanism to exec your versioning tool after compile/building - so your questions should be solved :-)

If you have any further questions don't hesitate to ask me.

PS: Here you can find more (undocumented) tricks around QMake: Undocumented QMake