[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Locating/Linking against Qt

From: Dalibor Topic
Subject: Re: Locating/Linking against Qt
Date: Sun, 28 Aug 2005 16:09:19 +0200
User-agent: Mozilla Thunderbird 1.0.6-1.1.fc4 (X11/20050720)

Brian wrote:
I believe this to be the relevant code from [1]. I am unclear as to where $PKG_CONFIG comes from. It's not an environment variable and not set by configure. [2] is the AutoQt macro for Qt 1-3.

Yep, that's the bit. pkg-config comes from PKG_CHECK_MODULES, which in turn invokes pkg-config to read the respective .pc files.

Since Trolltech does not seem to use Automake for building Qt 4 apps, but GNU Classpath does, I'll walk you through the code with some comments on what it does and why.

dnl Check for AWT related Qt4
  if test "x${COMPILE_QT_PEER}" = xyes; then
    PKG_CHECK_MODULES(QT, QtGui >= 4.0.1)

This bit uses pkg-config to check if the QtGui library exists in the version 4.0.1 or higher. pkg-config is a tool that reads .pc files, which in turn describe what CFLAGS and LDFLAGS are necessary to build something with some library.

GNU Classpath is using 4.0.1 since 4.0.0 had some serious linkage problems that prevented QX11EmbedWidget from working.

The pkg-config invocation sets some variables, with the prefix QT. So you'll get QT_CFLAGS and QT_LDFLAGS.

In order for pkg-config to work, it needs to be able to find the .pc files for Qt4. I.e. if you installed it yourself manually into ~/something, you need to tell pkg-config about it by adding the installtion/lib/ path (or wherever your installation of Qt4 managed to stuff the .pc files into) to the PKG_CONFIG_PATH environment variable.

    dnl Check needed because in some cases the QtGui includedir
    dnl doesn't contain the subsystem dir.

This bit is necessary because the CFLAGS from the Qt 4.0.x .pc flags have a "bad" include path. The include structure in a Qt 4 installation is

address@hidden ~]$ ls -l ~/qt4/include/
total 116
drwxrwxr-x  3 topic topic 24576 Aug 20 06:40 Qt
drwxrwxr-x  2 topic topic  8192 Aug 20 06:40 Qt3Support
drwxrwxr-x  2 topic topic  4096 Aug 20 06:41 QtAssistant
drwxrwxr-x  3 topic topic  8192 Aug 20 06:39 QtCore
drwxrwxr-x  2 topic topic  4096 Aug 20 06:41 QtDesigner
drwxrwxr-x  2 topic topic 12288 Aug 20 06:40 QtGui
drwxrwxr-x  2 topic topic  4096 Aug 20 06:40 QtNetwork
drwxrwxr-x  2 topic topic  4096 Aug 20 06:40 QtOpenGL
drwxrwxr-x  2 topic topic  4096 Aug 20 06:40 QtSql
drwxrwxr-x  2 topic topic  4096 Aug 20 06:39 QtXml

where all the includes are afaict accesible via the Qt subdirectory, and the includes for respective modules,like QtGui are present in those modules as well. So both <Qt/QWidget> and <QtGui/QWidget> are ok.

The .pc files set -Iwhereveryouputqt4/include in the CFLAGS.

The problem there is that noone, not even Trolltech actually puts those module prefixes in their #include paths. First of all, they are unnecessary if you are using qmake, Trolltech's cross-platform, Qt-specific automake-like tool. qmake sets the -I option in CFLAGS to include the name of the modules your code uses, so it actually sets -Iwhereveryouputqt4/include/QtGui in CFLAGS in the generated Makefiles.

Since most people use qmake to create Makefiles for their Qt projects, they use #include <QWidget> in their code, rather than #include <QtGui/QWidget>. So if you don't take care to work around what I believe is a bug in Trolltech's .pc files, you'll either have to mess with the #include statements of the code of people using qmake, or improve the QT_CFLAGS.

The code below does the latter.

    QT_INCLUDE_DIR=$($PKG_CONFIG --variable=includedir QtGui)

First it fetches the includedir for the QtGui library.


Then it appends "/Qt" to the includedir. That's the directory in a Qt4 installation where all the include files are present, so that one should make all Qt4 headers available to the compiler in a shorthand notation.


If the includedir in the pc file is OK, configure should be able to find QWidget in it, and don't need to append an extra include dir ending with "/Qt" to it.

                  AC_MSG_NOTICE([No extra QT_INCLUDE_DIR needed]),


Otherwise, the code checks if appending /Qt to the includedir leads to the QWidget include file. If that works, the extra include dir is added to the original QT_CFLAGS.

                        QT_CFLAGS="$QT_CFLAGS -I$EXTRA_QT_INCLUDE_DIR",
                        AC_MSG_WARN([QWidget not found])))

If none works, something strange has happened. Strange things may happen in the future when distributions start shipping qt4, for example, and may have to try to figure out ways to make it coexist with qt1/2/3/embedded versions that they are shipping as well. Distributions ocassionally do non-obvious things. In that case, the code prints a warning that it couldn't find the QWidget include file.


It also makes sure to tell that the QT_FLAGS have been set to something useful.

    AC_CHECK_PROG(MOC, [moc], [moc])

This bit checks for moc, a Qt-specific tool, which converts the Qt-C++ dialect's SIGNAL and SLOT shorthand macros into more standard C++ support files. It creates installation-specific .moc files.

Here, one more word of warning: some distributions ship the Qt4 moc under a different name, to make it coexist on the $PATH with the earlier versions. I've seen that Debian's unstable Qt4 package uses moc-qt4, too. You'll want to make sure that the plain "moc" from qt4 is on the $PATH before such renamed versions.

Moc from Qt3 will most likely *not* work with Qt4.

For how to use moc, see the cited below.

If you don't want to use automake for your Qt4 build fun, see Trolltech's Qt4 installation tarballs forn example projects, where internally, qmake is invoked to deal with the whole thing.

If you want to use qmake, check for qmake, of course. ;)


These bits take cure that the QT_* flags that the configure script has put so much work in by now, are actually made available to the Makefiles. ;)


And that's it. For how it is being used in practice, see*checkout*/classpath/classpath/native/jni/qt-peer/

It has worked fine for me (& Kaffe) on GNU/Linux and for others on OS X.
So you can marvel in the lovely Qt based AWT peers of GNU Classpath on those platforms, for all I know. I have not yet had the time to play with the Windows version.


I am also using the autoqt macros in Kaffe for the other set of Qt peers (Qt2/3/Embedded), and that's what they are really nice for. Since Qt4 comes with pkg-config support, though, and you probably really want to use Qt4 (the APIs are partially different from earlier versions, so your source will not build on them), then just going with the solution I explained above is simpler, than trying to update the autoqt macros for Qt4.

Note that contrary to earlier versions of Qt, with which autoqt deals just fine, as you can see in the Kaffe CVS head's m4 dir, Qt4 has split the core libraries into different modules, and changed a few other things about the default installation (header organisation, for example).

That might require a bit of work to make it all work fine if you decide to improve autoqt. I have not tried it myself, as the Qt peers in GNU Classpath only work with Qt4.

dalibor topic

reply via email to

[Prev in Thread] Current Thread [Next in Thread]