Home · All Classes · Annotated · Functions

Build System Internals

This document is designed for people who need to extend or modify the build system. If you are looking for information about using the build system (including writing .pro files) refer to: Build System User Guide and Build System Reference.

Environment Variables

The User Guide states that environment variables are not required, however, that is not strictly correct. The build system causes the environment variables to be set appropriately when building and the configure, qtopiamake and Makefile scripts handle this for you. However, there are various scripts that cannot be run without environment variables set. If they are run from one of the scritps above, they will be fine but manual running will cause problems.

The following variable is expected by configure:

The following variables can be defined if required:

The following table displays the variables that are set by configure and Makefile:

VariableDescription
QMAKEFEATURES
  • Set to $PROJECT_ROOT/features:$QTOPIA_DEPOT_PATH/src/build.
QTDIR
  • Set to $QPEDIR/qtopiacore/host for projects built for the host machine.
  • Set to $QPEDIR/qtopiacore/target for projects built for the target machine.
PREFIX
  • Set to $QPEDIR/image/opt/Qtopia.
DPREFIX
  • Set to $QPEDIR/dimage/opt/Qtopia.

The following table describes the variables that Makefile allows you to override:

VariableDescription
PREFIXChange where Qtopia is installed to.
DPREFIXChange where Qtopia Desktop is installed to.
DSee Debugging qmake for details.

Build Steps

The rest of the feature files are described below since they are not all loaded for any given project.

Features

Features are introduced in qmake 4 and have the following characteristics:

Note: When adding a new .prf file that matches one of the global files, to the project root features directory, be sure to load the global file unless you completely replace its functionality. For example:

    # $QPEDIR/tests/features/qtopiadesktop.prf
    load(qtopiadesktop) # get the Qtopia one

    # override something that we didn't like

The following table describes features that can be loaded after a project's .pro file . Note: Some of these files are described in more detail later:

FeatureDescription
common.prf
  • Set defaults (if not already set).
  • Add the include path to the depend path (so that other places don't need to worry about this).
  • Strange stuff to help the Qt switchover.
depends.prfProcess commands from projects that are dependencies.
i18n.prf
  • Set up make lupdate and make linstall rules.
  • Some of the Install Helpers are implemented here.
installs.prfMost of the Install Helpers are implemented here.
packages.prfCreate installable packages.
qtopia.prfQtopia-specific config.
qtopiadesktop.prfQtopia Desktop-specific configuration.
singleexec.prfSet up a singleexec build (Qtopia only).
stub.prfSet default values for stub projects.
subdirs.prf
  • Check SUBDIRS.
  • Partial tree building.
  • Set up recursive commands (lupdate, packages, sdk, devsdk, install_target, syncqtopia).
  • Smart ordering.

Install Prefixes

Items are installed to different locations depending on the edition and platform you are building for.

QtopiaQtopia Desktop
LinuxWindowsLinuxMac OS X
Binaries/bin//binSee note below
Libraries/lib//lib<bundle>/Frameworks
Plug-ins/plugins/plugins/qtopiadesktop/plugins<bundle>/Resources/plugins
Resources///qtopiadesktop<bundle>/Resources

Note:

  1. Resources includes everything that is not an application, library or plug-in.
  2. The situation with binaries on Mac OS X is unique. The binaries are actually located in:

As you can see, no locations are common between the supported configurations. The install_prefix feature provides the following variables that allow the install path to be set correctly:

Using these variables is not strictly required for Qtopia-only projects and there are some situations where you should not use them, including:

Debugging qmake

To display debug messages (including dependency statements) touch $QPEDIR/src/build/debug_on or export QMAKE_DEBUG_ON=1.

To display qmake debug run the command: make qmake-debug. You can specify more verbosity by running make qmake-debug D="-d -d -d" (more -d's indicates a more verbose debug).

To display when each build system file is processed touch $QPEDIR/src/build/trace_on. The output has more information than it should but there is no easy way to fix that. The following is an annotated example, showing which parts are relevant:

    These files are not read by your project.
    Project MESSAGE: .qmake.cache
    Project MESSAGE: default_pre.prf
    Project MESSAGE: functions.prf
    Project MESSAGE: config.prf
    Project MESSAGE: .qmake.cache

    Here is the real starting point that is, the last .qmake.cache before the first functions.prf.
    Project MESSAGE: .qmake.cache
    Project MESSAGE: default_pre.prf
    Project MESSAGE: functions.prf
    Project MESSAGE: config.prf
    Project MESSAGE: datebook.pro
    Project MESSAGE: default_post.prf
    Project MESSAGE: qtopia.prf
    Project MESSAGE: depends.prf

    These files are not read by your project.
    Project MESSAGE: START DEPENDENCIES
    Project MESSAGE: default_pre.prf
    Project MESSAGE: functions.prf
    Project MESSAGE: config.prf
    Project MESSAGE: qtopia.pro
    Project MESSAGE: default_pre.prf
    Project MESSAGE: functions.prf
    Project MESSAGE: config.prf
    Project MESSAGE: qtopiapim.pro
    Project MESSAGE: default_pre.prf
    Project MESSAGE: functions.prf
    Project MESSAGE: config.prf
    Project MESSAGE: quicklauncher.pro
    Project MESSAGE: INDIRECT DEPENDENCIES
    Project MESSAGE: default_pre.prf
    Project MESSAGE: functions.prf
    Project MESSAGE: config.prf
    Project MESSAGE: server.pro
    Project MESSAGE: END DEPENDENCIES

    These files are being read by your project.
    Project MESSAGE: i18n.prf
    Project MESSAGE: installs.prf
    Project MESSAGE: common.prf

Finding Files, Directories and Paths

The following table describes the variables available to help you locate files, directories and paths:

VariableDescripition
SRCDIR
  • The directory containing the application .pro file.
  • This is not available until after qtopia_project() has been called.
  • PWD can be used from the .pro file)
OUT_PWDDirectory containing the Makefile.
QPEDIRBuild tree.
QTOPIA_DEPOT_PATHSource tree.
PWDThe directory containing the currently-executing .pr[iof] file.

Note: This will change as each file is read).

QTDIRQt or Qtopia Core build tree (depending on what the current project uses).
QT_DEPOT_PATHQt or Qtopia Core source tree (depending on what the current project uses).
QTEDIRQtopia Core build tree.
QTE_DEPOT_PATHQtopia Core source tree.
DQTDIRQt build tree.
DQT_DEPOT_PATHQt source tree.

Note:

  1. The build system searches for files relative to PWD.
  2. qmake searches for files in a number of places, generally relative to SRCDIR, OUT_PWD and each location in VPATH.
  3. The Qt and Qtopia Core source trees are the same. The presence of both variables is for legacy purposes only.

Style

The following is a guide to style issues when coding:

Processing Order

Libraries must be processed before other projects that link to them. When qmake processes a library it creates a .prl file. When a project links to a library, qmake reads the .prl file. If the .prf file does not exist, qmake will guess the contents which can cause problems. The dependency system should be enough to prevent this from happening but to be sure, configure runs make syncqtopia to ensure all library directories are processed.

The build system installs headers based on install rules defined in .pro files. This means that projects cannot be built before the headers they depend on are installed. The dependency system should be enough to prevent this from happening but to be sure, configure runs make syncqtopia which causes the include directory to be set up.

Project Roots

The following files are expected (though optional) for each project root:

FileDescription
.qmake.cacheGenerated by qtopiamake.
tree_config.priSet up initial configuration and additional keywords.
features/implicit_deps.prfSet up implicit dependencies.

Building Qt/Qtopia Core

Qt/Qtopia Core is built by running make in the following locations:

Note: Do not build Qt/Qtopia core by enterin $QPEDIR/qtopiacore/[host|target].

Command Redirection

To override qmake-generated targets name them specially. The exception to this is the all target. The structure is redirect_<target> for example:

    redirect_clean.commands=@echo overriding the clean target
    QMAKE_EXTRA_TARGETS+=redirect_clean

The all target cannot be overridden but you can trigger a command to run at that time. This is mostly useful for stub projects as they do not build anything. For example:

    redirect_all.commands=@echo redirect_all
    ALL_DEPS+=redirect_all

There are some commands cannot be overriden:

    mytarget.commands=@echo regenerating
    QMAKE_EXTRA_TARGETS+=mytarget
    regenerate.depends+=mytarget

How Do I ...

... add a custom compiler?

The following is an example to compile some Flex (Lex) and Bison (YACC) files. These examples are useful because qmake's built-in support for these compilers is limited.

Note: This solution can only support one Flex and one Bison source file per project.

    FLEX_SOURCES=lexer.l
    BISON_SOURCES=parser.y

    flex.commands=flex -o${QMAKE_FILE_OUT} ${QMAKE_FILE_IN}
    flex.output=$$OUT_PWD/${QMAKE_FILE_BASE}.c
    flex.input=FLEX_SOURCES
    flex.variable_out=SOURCES
    flex.name=flex ${QMAKE_FILE_IN}
    # qmake can't parse lexer.l to see this dependency
    flex.depends=parser.h
    QMAKE_EXTRA_COMPILERS+=flex

    bisonsource.commands=bison -d -o${QMAKE_FILE_OUT} ${QMAKE_FILE_IN}
    bisonsource.output=$$OUT_PWD/${QMAKE_FILE_BASE}.c
    bisonsource.input=BISON_SOURCES
    bisonsource.variable_out=SOURCES
    bisonsource.name=bisonsource ${QMAKE_FILE_IN}
    QMAKE_EXTRA_COMPILERS+=bisonsource

    # This dummy entry is required so that qmake handles the header correctly
    bisonheader.commands=@true
    bisonheader.output=$$OUT_PWD/${QMAKE_FILE_BASE}.h
    bisonheader.input=BISON_SOURCES
    bisonheader.variable_out=HEADERS
    bisonheader.name=bisonheader ${QMAKE_FILE_IN}
    # this dependency is required so that files that depend on parser.h are processed after Bison is run
    bisonheader.depends=parser.c
    QMAKE_EXTRA_COMPILERS+=bisonheader

... use install rules at other times?

You need to set the following CONFIG:

    foo.CONFIG=no_default_install

This makes the rule exist but does not force the install target depend on it. For example, the headers hint uses this so that the rules for setting up the include directory do not trigger when you run make install.

... run some commands before the target is built?

It is somewhat tricky to get your code to run before the target is built. The easiest way is to create a compiler that outputs to the HEADERS or SOURCES variable.

    # This crap is needed to generate datasets.h
    GENERATOR=make_test_data.pl
    dataset.commands=$$COMMAND_HEADER\
        $$PWD/make_test_data.pl ${QMAKE_FILE_OUT}
    dataset.output=$$OUT_PWD/datasets.h
    dataset.input=GENERATOR
    dataset.variable_out=HEADERS
    dataset.name=Generate ${QMAKE_FILE_OUT}
    QMAKE_EXTRA_COMPILERS+=dataset

You need to #include the generated file in some other file to force this to run first.

... run some commands after the target is built?

You can force your target to run after the target is built by depending on it. Note: The use of the Makefile variable.

    foo.depends+=$(TARGET)

... make my project get processed last?

You can use fake dependencies to do this. However, src/build/extra already does this so you can just depend on it or put your commands in there.


Copyright © 2006 Trolltech Trademarks
Qtopia 4.1.7