autoconf
[Top][All Lists]
Advanced

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

Re: Locating/Linking against Qt


From: Brian
Subject: Re: Locating/Linking against Qt
Date: Sun, 28 Aug 2005 13:01:07 -0600

Dalibor, thanks for this excellent explanation. I'm sure myself and others 
will refer to it again and again.

Cheers,
Brian Mingus

On 8/28/05, Dalibor Topic <address@hidden> wrote:
> 
> 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.
> 
> > EXTRA_QT_INCLUDE_DIR="$QT_INCLUDE_DIR/Qt"
> 
> 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.
> 
> > AC_CHECK_FILE([$QT_INCLUDE_DIR/QWidget],
> 
> 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]),
> >
> >
> > AC_CHECK_FILE([$EXTRA_QT_INCLUDE_DIR/QWidget],
> 
> 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.
> 
> > AC_MSG_NOTICE([Set QT_CFLAGS... $QT_CFLAGS])
> 
> 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 Makefile.am <http://Makefile.am> 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. ;)
> 
> > AC_SUBST(QT_CFLAGS)
> > AC_SUBST(QT_LIBS)
> 
> 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. 
> ;)
> 
> > fi
> 
> And that's it. For how it is being used in practice, see
> 
> http://savannah.gnu.org/cgi-bin/viewcvs/*checkout*/classpath/classpath/native/jni/qt-peer/Makefile.am?rev=1.4&content-type=text/vnd.viewcvs-markup
> 
> 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.
> 
> > [2] 
> http://cvs.sourceforge.net/viewcvs.py/*checkout*/autoqt/autoqt/gwqt.m4
> 
> 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.
> 
> cheers,
> dalibor topic
>


reply via email to

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