Qt Extended Home · Build System Home · Reference · User Guide · Internals codeless banner

Porting to QBuild

Overview

See Introduction to QBuild for an introduction to QBuild. This guide shows how to port projects to QBuild.

One of the philosophies of QBuild is to make everything opt-in. Things are off by default and turned on only because the project requested them (directly or indirectly). Part of porting will involve turning on features your project had by default before.

Syntax

QBuild is not 100% syntax-compatible with qmake.

Variable Expansion

QBuild does not expand variables inside strings. You must

    #VAR="FOO is \$$FOO"
    VAR="FOO is $$FOO"

    #VAR="FOO is $$FOO, demonstrate catenation"
    VAR="FOO is "$$FOO", demonstrate catenation"

Embedded Quotes

To embed a quote character in a quoted string you must escape the character with itself (like in SQL). This compares to qmake's use of backslash as an escape character. These statements are equivalent.

    #VAR=one two three
    VAR=one two three

    #VAR="one two" three
    VAR="one two" three

    #VAR="one \"two\"" three
    VAR="one ""two""" three

For ease of embedding quotes in shell scripts and defines, there are several functions available. See shellQuote(), define_string() and define_value().

Group notation

QBuild allows a group notation that is handy when defining objects.

    #FOO.TYPE=object
    #FOO.FOO=foo
    #FOO.BAR=bar
    FOO [
        TYPE=object
        FOO=foo
        BAR=bar
    ]

Projects

There are a number of changes that must be made. They are described by name or by topic.

Implicit Variables

None of the implicit variables exposed by qmake are available. The two most used of these have replacements.

    #VAR=$$PWD
    VAR=$$path(.,project)

    #VAR=$$OUT_PWD
    VAR=$$path(.,generated)

Explicit Variables

A number of variables are no longer set by the build system.

    #VAR=$$QPEDIR
    VAR=$$path(/,generated) # only for projects inside the Qt Extended tree
    VAR=$$path(QtopiaSdk:/,generated) # for all projects

    #VAR=$$QTOPIA_DEPOT_PATH
    VAR=$$path(/,project) # only for projects inside the Qt Extended tree

    #VAR=$$QTDIR
    CONFIG+=qt embedded
    qt_get_qtdir()
    VAR=$$QTDIR # returns the path to Qt Embedded in the SDK

    #VAR=$$QT_DEPOT_PATH
    VAR=$$path(/qtopiacore/qt,existing) # only for projects inside the Qt Extended tree

qtopia_project()

This function achieved several things at once so there is no simple mapping. In general, the QBuild commands required to replace this function call are a straightforward combinations of options.

The keywords app, lib, plugin and subdirs become the TEMPLATE of the project.

    #qtopia_project(app)
    TEMPLATE=app

    #qtopia_project(lib)
    TEMPLATE=lib

    #qtopia_project(plugin)
    TEMPLATE=plugin

    #qtopia_project(subdirs)
    TEMPLATE=subdirs

See too the note on subdirs below.

The keyword qtopia becomes a CONFIG value.

    #qtopia_project(qtopia app)
    TEMPLATE=app
    CONFIG+=qtopia

Qt and Qt Embedded apps use CONFIG values too.

    #qtopia_project(desktop app)
    TEMPLATE=app
    CONFIG+=qt

    #qtopia_project(embedded app)
    TEMPLATE=app
    CONFIG+=qt embedded

Non-Qt projects simply omit that CONFIG value.

    #qtopia_project(desktop external app)
    TEMPLATE=app

    #qtopia_project(external app)
    TEMPLATE=app
    CONFIG+=embedded

The default project type in QBuild is the same as a stub project. Theme projects are no longer special.

    #qtopia_project(stub)

    #qtopia_project(theme)

The core keyword has no direct replacement. Required Qt and Qt Extended libs are set vi the QT and QTOPIA variables.

    # QtCore only
    QT=core

    # libqtopiabase only
    QTOPIA=base

The test keywords are now CONFIG values.

    #qtopia_project(unittest)
    CONFIG+=unittest

    #qtopia_project(integrationtest)
    CONFIG+=integrationtest

    #qtopia_project(systemtest)
    CONFIG+=systemtest

There is no replacement for the server_lib keyword. Server projects are directly included into a single project for building.

qtopia_main

There is no qtopia_main CONFIG value. Instead, an application specifies that they support quicklauncher or singleexec by adding them to CONFIG.

    # Using QTOPIA_MAIN, quicklaunch compatible
    CONFIG+=qtopia quicklaunch

    # Using QTOPIA_MAIN, quicklaunch and singleexec compatible
    CONFIG+=qtopia quicklaunch singleexec

If the CONFIG value does not include quickalunch then the singleexec CONFIG value indicates the app has a singleexec_main function (instead of using the QTOPIA_MAIN macro).

    # A non-quicklaunchable Qtopia app that is singleexec compatible
    CONFIG+=qtopia singleexec

    # A Qt app that is singleexec compatible
    CONFIG+=qt embedded singleexec

    # An app that is singleexec compatible
    CONFIG+=embedded singleexec

Embedded apps that do not link to Qt and do not have CONFIG+=singleexec will be built as standalone binaries. Apps that link to Qt will not be built unless they have CONFIG+=singleexec (they would end up very large due to the static linking).

depends()

The replacement for depends() is MODULES. Generally, the last part of the name is what is required. The exact value is whatever the project you depend on specifies as its MODULE_NAME.

    #depends(libraries/handwriting)
    MODULES+=handwriting

Fake dependencies are not supported. In most cases, this was to support using headers. A selector notation allows this to work in QBuild.

    #INCLUDEPATH+=.../handwriting
    #depends(libraries/handwriting,fake)
    MODULES+=handwriting::headers

See MODULES for the complete reference on what can be specified using the selector notation and how this is implemented.

Note that is is preferred to use the QTOPIA variable for Qt Extended libs (it matches the QT variable used for Qt libs). Also, some modules will have different names (since there were some name clashes.

    #depends(libraries/qtopiamail)
    CONFIG+=qtopia
    QTOPIA+=mail

dep/idep

These commands are replaced by an object with a list of commands to be run. Note that the name of the object can be used as a selector. See MODULES for the complete reference on what can be specified using the selector notation and how this is implemented.

    #dep(CONFIG+=foo)
    myobj.TYPE=DEPENDS
    myobj.EVAL="CONFIG+=foo"

Multiple values can be on separate objects or on the same object.

    #dep(CONFIG+=foo)
    #dep(CONFIG+=bar)
    myobj.TYPE=DEPENDS
    myobj.EVAL=\
        "CONFIG+=foo"\
        "CONFIG+=bar"

    #dep(CONFIG+=foo)
    myobj.foo.TYPE=DEPENDS
    myobj.foo.EVAL="CONFIG+=foo"
    #dep(CONFIG+=bar)
    myobj.bar.TYPE=DEPENDS
    myobj.bar.EVAL="CONFIG+=bar"

QBuild recognizes two kinds of persisted dependencies. Those that apply only to the current build tree and those that persist into the SDK.

    #idep(CONFIG+=foo)
    myobj.TYPE=DEPENDS PERSISTED
    myobj.EVAL="CONFIG+=foo"

    #idep(CONFIG+=foo)
    myobj.TYPE=DEPENDS PERSISTED SDK
    myobj.EVAL="CONFIG+=foo"

The awkward alternate form where the command is to be run in the same project is simpler.

    #idep(CONFIG+=foo,CONFIG)
    myobj.TYPE=DEPENDS PERSISTED METOO
    myobj.EVAL="CONFIG+=foo"

i18n

The no_tr CONFIG value is gone. Instead, all projects must register their ability to be translated by setting STRING_LANGUAGE and LANGUAGES. If the STRING_LANGUAGE is included in LANGUAGES a plural-only translation file is created.

    STRING_LANGUAGE=en_US
    LANGUAGES=en_US de

The optional variable AVAILABLE_LANGUAGES allows qbuild lupdate to operate on a larger list of languages than is installed. This is primarily aimed at Qt Extended which creates translations for a large number of languages but installs translations for a smaller set.

    STRING_LANGUAGE=en_US
    LANGUAGES=$$QTOPIA_LANGUAGES
    AVAILABLE_LANGUAGES=$$QTOPIA_AVAILABLE_LANGUAGES

The TRANSLATABLES variable is gone. In its place is a conditional sources mechanism.

    #TRANSLATABLES+=foo.cpp
    #condition:SOURCES+=foo.cpp
    mycond.TYPE=CONDITIONAL_SOURCES
    mycond.CONDITION=condition
    mycond.SOURCES=foo.cpp

There are caveats to the conditional sources mechanism. See conditional_sources Extension for more information.

plugins

The build system no longer guesses what system a plugin is for and what type it is. These must be explicitly stated.

    PLUGIN_FOR=qt
    PLUGIN_TYPE=kbddrivers

    PLUGIN_FOR=qtopia
    PLUGIN_TYPE=mediaengines

A plugin that is loaded by Qt can depend on Qt Extended (eg. to get qLog) as long as the app that loads the plugin also depends on Qt Extended.

INSTALLS

The INSTALLS variable is no longer used. The .hint values are used to locate the install objects. One consequence of this is that some objects need .hint=image added.

    #INSTALLS+=foo
    foo.hint=image
    foo.files=foo.txt
    foo.path=/foo

Complete examples

Application

Here is an example .pro file before porting.

    qtopia_project(qtopia app)
    TARGET=example
    CONFIG+=qtopia_main

    AVAILABLE_LANGUAGES=en_US
    LANGUAGES=$$AVAILABLE_LANGUAGES

    FORMS=examplebase.ui
    HEADERS=example.h
    SOURCES=main.cpp example.cpp

    desktop.files=example.desktop
    desktop.path=/apps/Applications
    desktop.trtarget=example-nct
    desktop.hint=nct desktop
    INSTALLS+=desktop

    pics.files=pics/*
    pics.path=/pics/example
    pics.hint=pics
    INSTALLS+=pics

    help.source=help
    help.files=example.html
    help.hint=help
    INSTALLS+=help

    target.hint=sxe
    target.domain=untrusted

    pkg.name=example
    pkg.desc=Example Application
    pkg.version=1.0.0-1
    pkg.maintainer=Qt Extended <info@qtextended.org>
    pkg.license=Commercial

Here are the bits that have changed.

    #qtopia_project(qtopia app)
    TEMPLATE=app
    CONFIG+=qtopia

    #CONFIG+=qtopia_main
    CONFIG+=quicklaunch singleexec

    #AVAILABLE_LANGUAGES=en_US
    #LANGUAGES=$$AVAILABLE_LANGUAGES
    STRING_LANGUAGE=en_US
    LANGUAGES=en_US de

    #INSTALLS+=desktop

    #INSTALLS+=pics

    #INSTALLS+=help

Here is the complete exmple application after porting.

    TARGET=example
    CONFIG+=qtopia
    CONFIG+=quicklaunch
    CONFIG+=singleexec

    STRING_LANGUAGE=en_US
    LANGUAGES=en_US de

    pkg.name=example
    pkg.desc=Example Application
    pkg.version=1.0.0-1
    pkg.maintainer=Qt Extended <info@qtextended.org>
    pkg.license=Commercial

    FORMS=examplebase.ui
    HEADERS=example.h
    SOURCES=main.cpp example.cpp

    desktop.hint=nct desktop
    desktop.files=example.desktop
    desktop.path=/apps/Applications
    desktop.trtarget=example-nct

    pics.hint=pics
    pics.files=pics/*
    pics.path=/pics/example

    help.hint=help
    help.source=help
    help.files=example.html

    target.hint=sxe
    target.domain=untrusted

Third-party library stub

Here is a third-party library stub.

    qtopia_project(stub)
    idep(LIBS+=-lasound)

Here is the ported project.

    MODULE_NAME=alsa
    DEP.libs [
        TYPE=DEPENDS PERSISTED SDK
        EVAL="LIBS+=-lasound"
    ]

See also Tasks.


Copyright © 2009 Nokia
Qt Extended - Build System Documentation