[kde-freebsd] A few notes about the Qt4 ports for porters

Michael Nottebrock lofi at freebsd.org
Mon Feb 5 21:59:59 CET 2007


This is a rather verbose mail. Skip towards the end for some quick
explanations with hands-on examples.

There are two import differences between the qt4 ports and qt33: Qt4
lives in ${LOCALBASE} instead of ${X11BASE} and qt4 is not a single
monolithic port, but many individual ports and one (entirely
optional) metaport (devel/qt4). The metaport is provided mostly for the
benefit of developers and porters and should *not* be depended on by
other ports. It will pull in all other qt4 component ports except for
misc/qt4-qtdemo.


Makefile Variables/Switches
===========================

To depend on qt4 or individual parts of qt4, porters need to specify

USE_QT_VER=4

in their port Makefiles. Specifying nothing but this switch will
trigger a dependency on the qt4 metaport. The switch enables an
additional variable:

QT_COMPONENTS

QT_COMPONENTS can be used to list Qt4 tool and library dependencies
in a specific and concise fashion. The complete list of
possible values of QT_COMPONENTS can be found in
${PORTSDIR}/Mk/bsd.kde.mk in the _QT_COMPONENTS_ALL variable.

The most important components for porters are:

The libraries:

corelib gui network opengl qt3support qtestlib sql xml

All libraries themselves depend on corelib, so unless the application
you are porting uses nothing but corelib, corelib doesn't need to be
explicitly specified. You can determine which libraries the
application depends on, by running
ldd </path/to/main-executable> | grep Qt
after a successful compilation.

The tools:

moc qmake rcc uic

You will almost certainly need to depend on moc regardless what type
of application you are porting. If the application in question uses a
GUI, uic will be needed, too. Dependence on rcc can be determined by
looking for *.rc or *.qrc files in the application's source code
directories.

Note that moc and uic are installed as "moc4" and "uic4" in order to
not conflict with qt33. qmake is installed as "qmake-qt4"
in order to not conflict with Qt3's qmake. Applications that use qmake
as a buildsystem or query qmake for Qt's configuration will figure
this out automatically, other buildsystems might require additional
environment variables, configure switches or even patches in order to
work.

The plugins:

iconengines imageformats

You should specify imageformats if your application ships image files
which are loaded and displayed within your application. You should
specify iconengines if your application ships with SVG icons which
are used in the application's GUI. If in doubt, specify both, or users
might see a crippled user interface.

Environment
===========

Specifying USE_QT_VER=4 in a port Makefile will set some useful
environment variables to these default values:

QT_PREFIX=     ${LOCALBASE}
MOC=           ${QT_PREFIX}/bin/moc4
UIC=           ${QT_PREFIX}/bin/uic4
QMAKE=         ${QT_PREFIX}/bin/qmake-qt4
QMAKESPEC=     ${QT_PREFIX}/share/qt4/mkspecs/freebsd-g++

QTCPPFLAGS	(empty)
QTCGFLIBS	(empty)

It will also influence ${CONFIGURE_ENV}:

MOC="${MOC}" UIC="${UIC} CPPFLAGS="${CPPFLAGS}
${QTCPPFLAGS}" LIBS="${QTCFGLIBS}" QMAKE="${QMAKE}
QMAKESPEC="${QMAKESPEC}" QTDIR="${QT_PREFIX}" KDEDIR="${KDE_PREFIX}"

... and ${MAKE_ENV}

QMAKESPEC="${QMAKESPEC}"

${CONFIGURE_ARGS} are appended with:

--with-qt-includes=${QT_PREFIX}/include
--with-qt-libraries=${QT_PREFIX}/lib
--with-extra-libs=${LOCALBASE}/lib
--with-extra-includes=${LOCALBASE}/include

The modification of CONFIGURE_ENV and CONFIGURE_ARGS can be
suppressed by defining QT_NONSTANDARD in your port Makefile.


Example
=======

Note: *Do not use the actual qt4-* ports themselves as references*.

They are quite special (read: full of bad hacks and generally ugly),
since Qt doesn't really support being built component-by-component.

The editors/texmaker port can be used as reference for a typical Qt4
application that uses Qt's own qmake build system.

Let's look at the port Makefile:

[...]
USE_QT_VER=     4
QT_COMPONENTS=  gui moc qmake rcc uic
[...]

USE_QT_VER=4 enables the QT_COMPONENTS variable. The value of
QT_COMPONENTS, 'gui moc qmake rcc uic', triggers dependencies on the
qt4-gui, qt4-moc, qmake4, qt4-rcc and qt4-uic ports.

How to find out what components are needed by the application?

In this case, the INSTALL document only contains the instructions
"To compile and install Texmaker (Unix and MacosX): sudo sh BUILD.sh".
Looking at BUILD.sh, we find the line:

qmake -unix PREFIX=$PREFIX texmaker.pro

Apparently this application uses qmake, so we need 'qmake' added to
QT_COMPONENTS. As mentioned above, 'moc' is required by virtually
every qt application. Texmaker uses a GUI and there are files
with the .ui extension among the source code, thus we need
'uic'. There is also a .qrc file, which needs 'rcc' for processing.

Examination of the binary with ldd yields:

$ ldd /usr/local/bin/texmaker | grep Qt
libQtGui.so.4 => /usr/local/lib/libQtGui.so.4 (0x281c9000)
libQtCore.so.4 => /usr/local/lib/libQtCore.so.4 (0x28a01000)

The application links against the Qt gui and core libraries. Since
the core library is an implicit dependency of all other Qt4
libraries, it doesn't need to be specified. Our QT_COMPONENTS are now
complete: gui moc qmake rcc uic

What about the configure target?

Qmake allows for much flexibility with regards to how it is run and
what it is run on, which is why a generic configure target for
qmake isn't provided by bsd.kde.mk. With the provided environment it
is however quite easy to write your own:

[...]
HAS_CONFIGURE=	yes

do-configure:
        @cd ${WRKSRC} && ${SETENV} ${CONFIGURE_ENV} \
                ${QMAKE} -unix PREFIX=${PREFIX} texmaker.pro
[...]

Note the similarity to the qmake line from the provided BUILD.sh
script. The ${SETENV} ${CONFIGURE_ENV} ensures qmake will see the
QMAKESPEC variable, without which it cannot work.

Qmake generates standard Makefiles, so it is
not necessary to write our own build or configure targets.

Any other things to watch out for?

Qt applications often are written to be cross-platform and often
X11/Unix isn't the platform they are developed on, which in turn often
leads to certain loose ends, like:

- Missing additional includepaths. Many
applications come with system tray icon support, but neglect to look
for includes and/or libraries in the X11 directories. You can
tell qmake to add directories to the include and library searchpaths
via the commandline, for example:

${QMAKE} -unix PREFIX=${PREFIX} INCLUDEPATH+=${X11BASE}/include \
LIBS+=-L${X11BASE}/lib sillyapp.pro

- Bogus installation paths. Sometimes data such as icons or .desktop
files are by default installed into directories which aren't scanned
by XDG-compatible applications. editors/texmaker is an example for
this - look at patch-texmaker.pro in the files directory of that port
for a template on how to remedy this directly in the Qmake project
file.

A final note: At the moment, bsd.kde.mk isn't pre/postmk-safe, which
means you cannot use USE_QT_VER and QT_COMPONENTS after an .include
<bsd.port.pre.mk>. If your port requires this, please depend on the
component you need the traditional way for now, for example:

.include <bsd.port.pre.mk>

.if defined(WITH_QT_SUPPORT)
BUILD_DEPENDS+=	moc4:${PORTSDIR}/devel/qt4-moc
LIB_DEPENDS+=	QtCore:${PORTSDIR}/devel/qt4-corelib
.endif

.include <bsd.port.post.mk>

-- 
   ,_,   | Michael Nottebrock               | lofi at freebsd.org
 (/^ ^\) | FreeBSD - The Power to Serve     | http://www.freebsd.org
   \u/   | K Desktop Environment on FreeBSD | http://freebsd.kde.org
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 187 bytes
Desc: not available
Url : http://mail.kde.org/pipermail/kde-freebsd/attachments/20070205/885accb7/attachment-0001.pgp 


More information about the kde-freebsd mailing list