Friday, February 12, 2010

Qt Library Dependencies -- rebuilding dependencies with qmake

Left-click to Download the Sample Project

I modularize my projects into multiple libraries. The best reason is Separation of Concerns, but it also allows each library to link with its own unit test.

There's an app, then there are several libraries that the app depends upon.

I'll organize my system as such:
TrialSystem/TrialSystem.pro
TrialSystem/trialApp/trialApp.pro
TrialSystem/trialLibA/trialLibA.pro
Now, trialApp depends on trialLibA, therefore if anything changes in trialLibA, I want the build system to first rebuild trialLibA then link that newly built library into trialApp. (I'm building static libraries).

One solution to this problem uses the "subdirs" template for the TrialSystem.pro file. This solution requires the entire system to be in the same directory hierarchy, and it precludes parallel builds (if possible, the build system spins multiple threads to spread the load across multiple processors).

-- This is not possible through the menus of Qt Creator. --

First, create System.pro. It should have this content:
TEMPLATE = subdirs
SUBDIRS = trialLibA trialApp
CONFIG += ordered
This qmake project file builds the subdirectories "trialLibA" and "app" in that order. Now, if anything has changed in the library, the library is built first, then the app is relinked.

One nice feature of this setup is that when Qt Creator opens System.pro, it automatically shows the "app" and "libA" projects in the Projects window.

The project file trialLibA.pro has this content. This is a pretty straightforward static library:

TARGET = trialLibA
TEMPLATE = lib
CONFIG += staticlib
CONFIG += create_prl
SOURCES += TrialLibA.cpp
HEADERS += TrialLibA.h
The application's project file, trialApp.pro has this content. This is a mingw build under Windows (thanks for the formatting, Mr. Blogger.com):
TARGET = trialApp
TEMPLATE = app

win32 {
CONFIG(debug, debug|release) {
LIBS += -L../trialLibA/debug
PRE_TARGETDEPS += ../trialLibA/debug/libtrialLibA.a
} else {
LIBS += -L../trialLibA/release
PRE_TARGETDEPS += ../trialLibA/release/libtrialLibA.a
}
}

INCLUDEPATH += ../trialLibA
LIBS += -ltrialLibA

SOURCES += main.cpp\
MainWindow.cpp
HEADERS += MainWindow.h
FORMS += MainWindow.ui

Note the addition of PRE_TARGETDEPS. This unfortunate platform-specific code (it specifies the precise name of the library along with its path) forces trialApp to relink if the library changes.

Now, it's possible to change something down in trialLibA.cpp, hit "F5" and have the application run correctly in debug mode.

Now, these acrobatics shouldn't be necessary if qmake supported proper dependency trees automatically.

http://lists.trolltech.com/qt-interest/2007-03/thread00794-0.html

http://www.qtcentre.org/threads/28049-qmake-Project-file-has-both-debug-and-release-conditions-true

No comments:

Post a Comment