| Home · All Classes · Annotated · Functions |
This document is designed for anyone working with the Qtopia build system. It is used in conjunction with the Build System Reference which describes individual items in more detail and the Build system Internals document that provides additional developer-oriented information.
| Term | Description |
|---|---|
| Qt |
|
| Qtopia Core |
|
| source tree |
|
| build tree |
|
| project root |
|
| project |
|
| internal project |
|
| external project |
|
Note: Qt and Qtopia Core share the same sources but must be built as two separate products, even when building for the desktop.
If you have used earlier Qtopia releases there are some significant changes to how the build system works as follows:
For definition purposes, the build system comprises the following files:
| File | Description |
|---|---|
| configure | The initial entry point into the build system used to set up the build tree. |
| bin/qtopiamake | Called by configure and doubles as the the initial entry point for external projects. |
| bin/*.pm | Support modules for the perl scripts that comprise the build system. |
| Makefile | Second entry point into the build system. Makefiles are created by qtopiamake. |
| Makefile.target | File created by qmake for each project. It should not be called directly. |
| *.pro | File read by qmake when it makes Makefile.target. There is one of these files for each project. |
| *.prf | Features files that can be loaded explicitly but are typically loaded implicitly. |
| *.pri | These are miscellaneous build system files included from .pro or .prf files. |
Qtopia builds on Linux using GNU make. It should not be difficult to build on other Unix-like systems, though non-GNU make utilities might be a problem and due to assumptions made in the build system, building under Cygwin may prove difficult. Building without a make tool that is, qmake's XCode/Visual Studio project generation is not possible as parts of the the build system functionality are based on running Makefiles.
When editing source files and shadow building (that is, build tree != source tree) you may be interested in depot hopping. Simply set QPEDIR to the location of your build tree and the Makefiles that qtopiamake puts in the source tree will call through to those in the build tree. For example:
cd /path/to/build
export QPEDIR=$PWD
cd /path/to/source/examples/application
$QPEDIR/bin/qtopiamake # sets up shadow build to $QPEDIR/examples/application
make # build in $QPEDIR/examples/application
The Qtopia build system has dependency information embedded into the .pro files. This makes it possible to build everything in the most efficient way as well as providing flexibility. For example, a library can be renamed with a single change in a single file whereas without the dependency system, many files would need to be changed. The dependency information also provides the ability to graph interdependencies between projects as well as dependencies on external libraries.
Note: Do not put LIBS+= or INCLUDEPATH+= lines in your .pro files, use depends() instead. This applies even if you need to depend on something that isn't built (ie. part of the system). Simply create a stub project with dep() commands. This keeps dependencies clearly defined.
If your application can handle a missing dependency you should do something like this:
contains(PROJECTS,mydep):CONFIG+=enable_mydep
enable_mydep:depends(mydep)
else:DEFINES+=QTOPIA_NO_MYDEP
Use the presence or absence of enable_mydep in the .pro file. For example, disable whole files that use the dependency. Use the presence or absence of QTOPIA_NO_MYDEP to handle code that interfaces with the dependency.
For information about how to use the dependency system please refer to the dep(), idep() and depends() functions.
Qtopia applications can be built in one of four ways:
To facilitate switching between build modes, Qtopia provides two macros which are used as follows:
#include "myheader.h"
#include <QtopiaApplication>
QTOPIA_ADD_APPLICATION(QTOPIA_TARGET, MyMainClass)
QTOPIA_MAIN
The first argument to QTOPIA_ADD_APPLICATION() must be a literal string that matches the binary name that is, the value of TARGET from the .pro file. The build system defines QTOPIA_TARGET with the value of TARGET and it is recommended to use this macro.
The second argument to QTOPIA_ADD_APPLICATION() should be the name of your class. If you use the wrong value you will get a compile failure.
Building for either quicklaunch or singleexec (quicklaunch) requires these macros but the build system cannot easily determine if you have used them and the penalty for a wrong guess could be disastrous. Therefore you must use the qtopia_main CONFIG value if you use these macros or the build system will assume your application is not quicklaunch-compatible. If your application does not handle quicklaunch or is singleexec you can use the no_quicklaunch or no_singleexec CONFIG values.
For example, games do not need the speed benefits of quicklauncher (and there is a size penalty for using quicklauncher) but they do work with singleexec. So use CONFIG+=qtopia_main no_quicklaunch to indicate this.
Some applications, such as those using a custom application class, cannot use the macros. Tis prevents the use of quicklauncher but you can still work with singleexec if you make some changes to your code. You need to use the singleexec_main CONFIG value and have a main.cpp similar to the following:
#include "myheader.h"
#include <QtopiaApplication>
#ifdef SINGLE_EXEC
QTOPIA_ADD_APPLICATION(QTOPIA_TARGET, MyMainClass)
#define MAIN_FUNC main_MyMainClass
#else
#define MAIN_FUNC main
#endif
int MAIN_FUNC( int argc, char **argv )
{
MyApplication a( argc, argv );
MyWidget w;
w.show();
return a.exec();
}
Library projects .pro files require extra code to make them usable by other projects, for example:
qtopia_project(lib)
TARGET=mylib
PREFIX=MYLIB
MYLIB_FORMS=foobase.ui
MYLIB_HEADERS=foo.h
MYLIB_PRIVATE_HEADERS=foo_p.h
MYLIB_SOURCES=foo.cpp
resolve_include()
mylib_headers.files=$$MYLIB_HEADERS
mylib_headers.path=/include/qtopia/mylib
mylib_headers.hint=headers
INSTALLS+=mylib_headers
mylib_private_headers.files=$$MYLIB_PRIVATE_HEADERS
mylib_private_headers.path=/include/qtopia/mylib/private
mylib_private_headers.hint=headers
INSTALLS+=mylib_private_headers
idep(LIBS+=-l$$TARGET)
qt_inc($$TARGET)
This project is a library project called mylib. The use of PREFIX, MYLIB_* and resolve_include() is not strictly required but will help if the library needs to be extended later.
There are some install rules created and qt_inc() is used to setup the headers. See Setting Up Headers for details.
The use of idep() ensures that dependent projects will be linked to this library.
External plug-ins will need to set the plugin_type variable so that the build system knows what type of plug-in they are.
A project that uses the keyword subdirs to qtopia_project() will cause other directories to be built. The project at the top of each project root specifies a value for subdirs, however there are many projects that do not and subdirs projects that are inside a project root will cause part of the tree to be built. It is also possible to build all directories (instead of those listed in PROJECTS) by using the build_all_dirs CONFIG value. This is superior to using recursive subdirs as it allows dependencies to be processed.
To simplify the code required in each .pro file and to aid installation, common functionality has been moved into the build system. This is mostly visible through the use of Install Hints and is assisted by the use of the EXTRA_TS_FILES variable.
Qtopia projects are automatically setup to be built into packages, and by default these are single packages. Non-qtopia projects must add packages to their CONFIG to be built into packages. The package contents are the result of running make install. To configure the default package you should use the pkg structure, for example:
pkg.name=myapp
pkg.desc=My Great App
pkg.version=1.0
You can create other structures and assign them to the PACKAGES variable to create more than one package though this is not well tested. The structure of a packaging structure is as follows:
# struct package {
# name # eg. $name.ipk
# desc # one line summary
# domain # SXE security domains
# deps # packages that this ipk depends on
# multi # additional projects that should be included in this package
# version # package version
# license # package license
# maintainer # package maintainer
# targets # targets to run (ie. install stuff)
# }
The use of pkg structure is suppressed by adding the no_pkg CONFIG value. This is useful for multi-project packages, for exmaple, several network-related projects are put into one package. To improve maintainability, you should indicate which project is responsible for packaging if you do this, for example:
# Packaged by settings/network
CONFIG+=no_pkg
The build system has a variable named TRANSLATABLES that is used to facilitate a single set of translations across a number of products and configurations. Conditional source should be added to the TRANSLATABLES variable even if the condition is false.
Non-code Translatables are processed with bin/nct_lupdate which extracts data from the following formats:
| Format | Description |
|---|---|
| zone.tab | A special case used to extract city names from the time zone database |
| QSettings | Format for Qtopia configuration files that deal with translated values. |
The following is an example of a translatable settings file:
[Translation]
File=QtopiaApplications
Context=Calendar
Comment[Desktop Entry/Name]=Use soft hyphen (char U00AD) to indicate hyphenation
[Desktop Entry]
Comment[]=A Calendar and Scheduling Program
Exec=datebook
Icon=datebook/DateBook
Type=Application
Name[]=Cal\xad\x65n\xad\x64\x61r
MimeType=text/x-vcalendar
In the above datebook.desktop example,the important parts are the [Translation] section and the Var[]=Value lines.
| Code Line | Description |
|---|---|
| File=QtopiaApplications | Instructs the build system to store the translations in a file called QtopiaApplications.ts. The files in Qtopia are generally stored in global .ts files but third-party applications need to use their own files. |
| Context=Calendar | Specifies the context to use for the translations. When QObject::tr() is called an implicit context is used, however, QApplication::translate() allows the context to be set. This must be somewhat unique so that translators do not have to deal with unrelated strings when translating content. |
| Comment[Desktop Entry/Name]=Use soft hyphen (char U00AD) to indicate hyphenation | Places a comment in the .ts file for translators. In this case, the value Name in the [Desktop Entry] section is given a comment. |
| Name[]=Cal\xad\x65n\xad\x64\x61r | When Qtopia reads this value, it will try to translate it. |
The header setup process is a little complicated. The following is a step-by-step process:
Note: It is possible to use idep(INCLUDEPATH+=$$PWD) but this is not recommended as you cannot limit the files accessible when this method is used. You also cannot keep private headers separated from public headers.
Place the following code in the optvar section of configure:
set_optvar( "myopt", +{
"set" => [ "%", "Enable myopt." ],
"unset" => [ "no-%", "Disable myopt." ],
"default" => 1,
"visible" => $qtopia_visref,
"autodep" => $qtopia_autoref,
});
Place the following code in the config_pri section of configure:
if ( opt("myopt") ) {
print CONFIG_PRI "CONFIG+=enable_myopt\n";
}
Place the following code in src/build/qtopia.prf:
# positive define (preferred)
enable_myopt:DEFINES+=QTOPIA_MYOPT
# negative define (to match the QT_NO_ style)
!enable_myopt:DEFINES+=QTOPIA_NO_MYOPT
Note: The use of a positively-worded option. It is much easier to determine what code does when the options are positively worded.
The file projects.pri includes other files to setup the PROJECTS and THEMES variables which control what is built.
The following files are included from src in the source tree:
| File | Description |
|---|---|
| general.pri | Projects and themes that are in all Qtopia source packages. |
| commercial.pri | Projects and themes that are only in commercial Qtopia source packages. |
| custom.pri | Overrides/additions for Qtopia. |
| desktop.pri | Projects that are in Qtopia Desktop. |
| custom_qd.pri | Overrides/additions for Qtopia Desktop. |
The following files are included from src in the build tree:
| File | Description |
|---|---|
| local.pri | Overrides/additions specific to a build. |
| local_qd.pri | Overrides/additions for Qtopia Desktop specific to a build. |
It is not recommended to modify general.pri and commercial.pri, instead you should use custom.pri and local.pri. The intent is for organization changes (that is, changes that will be part of a redistributed source package) to go into custom.pri and changes for individual developers to go into local.pri.
When adding projects, it is recommended to use *= to avoid the possibility of duplicate entries as duplicate entries can cause problems when you try to build. For example:
PROJECTS+=myproj
PROJECTS*=myproj # no duplicate
PROJECTS+=myproj # duplicate
A project can be removed using -= as follows:
PROJECTS-=myproj
Note: qmake does not consider it an error to remove a non-existent value so check for spelling errors if a removed project is still building.
CONFIG values that are set based on edition and configuration can be used when adding projects, for example, a PDA-specific application could be added with:
pda:PROJECTS*=myproj
In the situation where You might want to enable a project only if another project is enabled, you can check for the presence of a project with the qmake contains function as follows:
contains(PROJECTS,applications/mygreatapp):PROJECTS*=plugins/mygreatapp/time
The following targets should work everywhere and will descend into subdirectories unless otherwise noted:
| Target | Description |
|---|---|
| all | Build the target. |
| first | Same as all. Provided for compatibility with Qt (which uses all to mean both debug and release versions). |
| install | Run the install rules. |
| install_target | Install the target only (eg. the application binary). |
| cleaninstall | Remove the image (and dimage) directories before installing. (Only useful when used from the top of the tree). |
| lupdate | Update .ts files. |
| syncqtopia |
|
| packages | Make installable packages. See Packages for details. |
| sdk | Run the SDK rules. |
| devsdk | Run the DevSDK rules. |
| regenerate | Rebuild the Makefile for this project. Do not descend into subdirectories. |
| qmake | Same as regenerate but descends into subdirectories. |
| qmake-debug | Same as regenerate but turns on qmake debugging. |
| clean | Remove intermediate files (not everything). |
| disclean | Remove the target and Makefile.target. |
| remove_target | Remove the target so that make will cause it to be re-linked. |
| relink | Runs make remove_target and make so that all targets are re-linked. |
Device Configuration Profiles simplify the task of configuring Qtopia for a device. A single directory contains all of the configuration information required to build for the device. The profiles are located in the devices directory in the source tree and are activated by running:
configure -device foo
For a tutorial on the process of implementing a plug-in for a new device see : Tutorial: Implementing a Device Plug-in
The following sections describe how to customize the profiles:
Each feature of the Device Configuration Profiles is identified by the file that implements it.
Each device configuration profile can have a file named configure that specifies all the arguments required to configure for the new device. This simplifies the process as generally many configuration arguments are required.
When configure ... -device foo ... is run, configure checks for $QTOPIA_DEPOT_PATH/devices/device/configure and if it is found, configure re-launches itself with -device device replaced by the contents of the file.
The following is a sample configure file:
-edition phone -xplatform mydev -arch arm -no-qvfb
-release -displaysize 240x320 -quicklaunch
-defaultbuttons phone
-extra-qtopiacore-config -plugin-kbd-mydev
-extra-qtopiacore-config -plugin-mouse-mydev
-prefix /opt/Qtopia
Note:
For example, the sample file above specifies -release. Here is what would happen -debug is passed before and after -device foo:
{configure -debug -device foo}
becomes:
{configure -debug -release}
-release overrides -debug so a release build is performed.
{configure -device foo -debug}
becomes:
{configure -release -debug}
-debug overrides -release so a debug build is performed.
The environment script (if it exists) is sourced before re-running configure and before Makefile calls Makefile.target. The suggested use is to set up paths to an appropriate compiler with the DEVICE_CONFIG_PATH variable set to the path of the device configuration profile so that files inside the device directory can be located.
A typical behavior of the configure file is to set -xplatform so it is useful to have a platform specification for the device. Profiles can contain a mkspecs directory that is used to determine -platform and -xplatform speciification files. This allows a device to be built without having to modify the Qt depot (although it is possible to move a specification file to Qt without having to modify the configure line).
For example, the mydev specification files are in its configuration directory as follows:
devices/mydev/mkspecs/qws/linux-mydev-g++/qmake.conf
devices/mydev/mkspecs/qws/linux-mydev-g++/qplatformdefs.h
There are mkspecs that ship with Qtopia Core located in qtopiacore/qt/mkspecs/qws. You should copy one that is similar to your device, for example, linux-arm-g++, and modify it to suit your device. Be sure to check the compiler name and the compiler flags (especially optimization flags). You may also want the mkspec to specify a define to be used to enable device-specific code in Qtopia Core and Qtopia.
These files are device-specific and it is useful for them to be included in the Device Configuration Profile. If they are not present, configure will look in the traditional location, $QTOPIA_DEPOT_PATH/src/libraries/qtopia/custom-$xplatform.(h|cpp). See Hardware Configuration for information about custom.h.
Every device needs a suitable defaultbuttons.conf, However, use of this file only occurs if -defaultbuttons is not passed to configure. Refer to: Keypad Button Behavior for a description of defaultbuttons.conf.
Configuration tweaks can be done here. This is read just after the configure-generated config.pri, before each .pro file is read. A modified config.pri file is used to customize configuration. This file is read after the the config.pri file generated by configure and before each .pro file. Adding <content> to a config.pri file is equivalent to running the following:
configure -config <content>
The projects.pri file is used to enable and disable projects for a device. It is processed after general.pri and commercial.pri but before custom.pri and local.pri so that the user can still override the projects.
If the src directory exists, it is added as a project root that is:
configure -build $QTOPIA_DEPOT_PATH/devices/foo/src}
It is recommended to mimic the Qtopia source tree layout for ease of reference.
This file overrides the use of qconfig-qpe.h. It can define all new items or can include and override settings by using:
#include "qconfig-qpe.h"
Note: Beware of dependencies when including and overriding.
Profiles do not currently with the following:
| Copyright © 2006 Trolltech | Trademarks | Qtopia 4.1.7 |