summaryrefslogtreecommitdiffstats
path: root/src/doc/src/qtee-static-linking.qdoc
blob: 435778483d380516197da1c846afd909dfab7a60 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
/****************************************************************************
**
** Copyright (C) 2014 Digia Plc
** All rights reserved.
** For any questions to Digia, please use the contact form at
** http://www.qt.io
**
** This file is part of Qt Enterprise Embedded.
**
** Licensees holding valid Qt Enterprise licenses may use this file in
** accordance with the Qt Enterprise License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia.
**
** If you have questions regarding the use of this file, please use
** the contact form at http://www.qt.io
**
****************************************************************************/
/*!
    \page qtee-static-linking.html
    \title Linking to Static Builds of Qt
    \previouspage qtee-custom-embedded-linux-image.html
    \nextpage qtee-build-emulator.html

    The device-specific sysroots in \B2Q come with a dynamically linked version
    of Qt libraries (\c *.so files). In some cases, using static linking may be
    preferable; it avoids the dependencies to external libraries, produces
    single, self-contained application binaries making deployment easier,
    and may lead to smaller binary size as unused code can be stripped away.

    Internally, Qt uses dynamic linking with plugins for a lot of its functionality.
    In order to have a fully functioning application, extra attention is needed on
    which plugins to include in a static build. A downside of static linking is that
    adding or updating a plugin requires a complete rebuild and redeployment of the
    application.

    \section1 Requirements

    In addition to installing \SDK, ensure that required packages are installed for
    all Qt modules that are included in the static build. For more information, see
    \l {Qt for X11 Requirements#OpenGL Dependencies}{Qt for Linux Requirements} and
    \l {Qt for Linux/X11#Requirements for Development Host}{Requirements for
    Development Host}. Note that dependencies for the \e xcb platform plugin need
    not be installed, as Qt will be configured without xcb support.

    Install Qt sources by running the \e MaintenanceTool, located in the root of
    \c INSTALL_DIR. Alternatively,
    \l {https://wiki.qt.io/Building_Qt_5_from_Git#Getting_the_source_code}{clone}
    the \e qt5 repository using git.

    \section1 Building Qt for Static Linking

    To use static linking, Qt must be built with the \c -static configuration
    option. The following configure command selects the correct options and
    \e sysroot for the Raspberry Pi 2.

    To make the set of configure options reusable and more readable, the
    device-specific paths are defined as environment variables:

    \badcode
    export SYSROOT_BASE=<INSTALL_DIR>/5.6/Boot2Qt/raspberrypi2/toolchain/sysroots
    export TARGET_DEVICE=linux-rasp-pi2-g++
    export SYSROOT_TARGET=cortexa7hf-vfp-vfpv4-neon-poky-linux-gnueabi
    export CROSSCOMPILE_PREFIX=x86_64-pokysdk-linux/usr/bin/arm-poky-linux-gnueabi/arm-poky-linux-gnueabi-
    export HOST_PREFIX=~/build/qt5-rasp-pi2
    \endcode

    To configure and build Qt for some other device, modify the variables to
    contain the correct sysroot paths and device target strings as they appear
    in your \SDK installation.

    Description of the used variables:

    \table
    \row \li \c SYSROOT_BASE        \li Base directory for the sysroots
                                        (host and target) for the device

    \row \li \c TARGET_DEVICE       \li Target device (mkspec)

    \row \li \c SYSROOT_TARGET      \li Target sysroot directory under
                                        \c SYSROOT_BASE

    \row \li \c CROSSCOMPILE_PREFIX \li Cross-compilation toolchain path
                                        and tool prefix (ends with '-')

    \row \li \c HOST_PREFIX         \li Location to install the host
                                        binaries (qmake, moc, rcc, etc.)
    \endtable

    Using the above variables, \e configure can be called as follows:

    \badcode
    cd <QT_SRC>
    ./configure -commercial -release -static \
                -prefix /opt/qt5 -hostprefix $HOST_PREFIX \
                -device $TARGET_DEVICE \
                -device-option CROSS_COMPILE=$SYSROOT_BASE/$CROSSCOMPILE_PREFIX \
                -sysroot $SYSROOT_BASE/$SYSROOT_TARGET \
                -mysql_config $SYSROOT_BASE/$SYSROOT_TARGET/usr/bin/mysql_config \
                -psql_config /dev/null \
                -no-xcb -opengl es2 \
                -nomake tests -nomake examples \
                -skip qtwebengine
    \endcode

    Above, \c -prefix sets the intended destination of the Qt build on the
    device (sysroot). Running \c {make install} will, by default, install Qt under
    \c sysroot/prefix.

    Compiling in \e xcb support is disabled, OpenGL ES 2.0 support is selected,
    and \l [QtWebEngine] {Qt WebEngine} is excluded from the build, as it does
    not support static builds.

    More information about configure options is available in the \l [QtDoc]
    {Qt for Embedded Linux#Configuring a Specific Device}{Qt for Embedded Linux}
    documentation.

    If configuration is successful, proceed to build and install Qt:

    \badcode
    make -j6 && make install
    \endcode

    The host tools (in particular, qmake) are now installed in \c HOST_PREFIX,
    and the statically compiled Qt libraries are in
    \c $SYSROOT_BASE/$SYSROOT_TARGET/opt/qt5. At this point, it's also possible
    to add the new Qt version into Qt Creator and set up a \e Kit for it:

    \list
      \li \l {https://doc.qt.io/qtcreator/creator-project-qmake.html}{Qt Creator: Adding Qt Versions}
      \li \l {https://doc.qt.io/qtcreator/creator-targets.html}{Qt Creator: Adding Kits}
    \endlist

    \section1 Building a Static Application

    Building a stand-alone, static application requires all the necessary
    plugins to be also statically linked. By default, qmake compiles a set of
    plugins based on which Qt modules are used, and adds them to the \l
    [QMake] {QTPLUGIN} variable.

    After running qmake, the project directory contains a
    \c <target_name>_plugin_import.cpp file that imports the plugins
    using Q_IMPORT_PLUGIN() macros. The default set often contains more
    plugins than are actually needed; to prevent unnecessary bloat, it's
    possible to exclude certain plugin classes from the build.

    For example, to exclude additional image format plugins, use:

    \badcode
    QTPLUGIN.imageformats = -
    \endcode

    Alternatively, the automatic generation of Q_IMPORT_PLUGIN() macros can
    be turned off:

    \badcode
    CONFIG -= import_plugins
    \endcode

    The relevant plugins then need to be explicitly imported in the application
    code.

    For more information, see \l {How to Create Qt Plugins#Static Plugins}
    {Static Plugins}.

    \section2 Adding QML Imports

    Similar to how Qt plugins are imported, qmake invokes the
    \e qmlimportscanner tool to scan the application's .qml files, and
    generates a \c <target_name>_qml_plugin_import.cpp file containing a
    Q_IMPORT_PLUGIN() call for each static plugin associated with a QML import.

    For example, for a simple QML application using the \c QtQuick and \c
    QtQuick.Window import statements, the following statements are generated:

    \code
    Q_IMPORT_PLUGIN(QtQuick2Plugin)
    Q_IMPORT_PLUGIN(QtQuick2WindowPlugin)
    \endcode

    In addition, the resources used by the QML imports need to be made
    available to the QML engine. The best approach is to copy the files from
    the source location into the application's project directory and add them
    to the Qt resource system, together with the application's own resources.

    At minimum, even though an import plugin uses no extra resources (.qml,
    .js, or image files), its \e qmldir file needs to be accessible and
    located under the correct \l [QtQml] {QML Import Path} {QML import path}.

    For example, the following entries in a Qt resource collection file
    (.qrc) places the qmldir files under the \c qml/ prefix in resources:

    \badcode
    <file>qml/QtQuick.2/qmldir</file>
    <file>qml/QtQuick/Window.2/qmldir</file>
    \endcode

    Finally, the QML engine needs to be informed about the import path that's
    now located within the resources. The following implementation of \c main()
    sets the import path to \c qrc:/qml before loading \c main.qml:

    \code
    #include <QGuiApplication>
    #include <QQmlApplicationEngine>

    int main(int argc, char *argv[])
    {
        QGuiApplication app(argc, argv);

        QQmlApplicationEngine engine;
        engine.setImportPathList(QStringList(QStringLiteral("qrc:/qml")));
        engine.load(QUrl(QStringLiteral("qrc:/main.qml")));

        return app.exec();
    }
    \endcode
*/