How can I build fully static QT application in Linux?
Sorry for my English.
I want build QT application without dependencies from any shared libraries(qt libs and glibc and ALL libraries). For this I download QT sources, build it with -static option, check all *.a libraries by ldd. This libraries have not dependencies from shared .so lib. I install new QT libraries to /opt/Q5.8 and add /opt/Q5.8/bin to $PATH.
Then I create test Hello world project.
main .cpp:
#include using namespace std; int main(int argc, char *argv[])
CONFIG += debug console SOURCES += main.cpp QMAKE_LFLAGS += -static
[oleg@reffum qt_static]$ make g++ -static -o main main.o main_plugin_import.o -L/opt/Qt5.8/lib -L/opt/Qt5.8/plugins/platforms -lqwayland-egl -lwayland-egl -lqwayland-generic -lqwayland-xcomposite-egl -lqwayland-xcomposite-glx -lQt5WaylandClient -lXcomposite -lwayland-client -lwayland-cursor -lqxcb -L/opt/Qt5.8/plugins/xcbglintegrations -lqxcb-egl-integration -lqxcb-glx-integration -lQt5XcbQpa -lxcb-xinerama -lQt5LinuxAccessibilitySupport -lQt5AccessibilitySupport -lQt5GlxSupport -lXrender -lxcb-xkb -lxcb-sync -lxcb-xfixes -lxcb-randr -lxcb-image -lxcb-shm -lxcb-keysyms -lxcb-icccm -lxcb-shape -lxcb-glx -lXi -lSM -lICE -lxcb-render-util -lxcb-render -lxkbcommon-x11 -L/opt/Qt5.8/plugins/imageformats -lqgif -lqicns -lqico -lqjp2 -ljasper -lqjpeg -ljpeg -lqmng -lmng -lqtga -lqtiff -ltiff -lqwbmp -lqwebp -lwebp -lwebpdemux -L/opt/Qt5.8/plugins/egldeviceintegrations -lqeglfs-kms-egldevice-integration -lqeglfs-kms-integration -lQt5EglFsKmsSupport -lgbm -ldrm -lqeglfs-x11-integration -lQt5EglFSDeviceIntegration -lQt5EventDispatcherSupport -lQt5ServiceSupport -lQt5ThemeSupport -lQt5DBus -ldbus-1 -lQt5FontDatabaseSupport -lQt5FbSupport -lQt5EglSupport -lXext -lQt5PlatformCompositorSupport -lQt5InputSupport -lmtdev -linput -lxkbcommon -lQt5Gui -lpng16 -lharfbuzz -lQt5DeviceDiscoverySupport -ludev -lQt5Core -licui18n -licuuc -licudata -lm -ldl -lrt -lz -lpcre16 -lgthread-2.0 -lglib-2.0 -lxcb -lX11 -lX11-xcb -lfontconfig -lfreetype -lts -lEGL -lGL -lpthread /usr/bin/ld: cannot find -lwayland-egl /usr/bin/ld: cannot find -lXcomposite /usr/bin/ld: cannot find -lwayland-client /usr/bin/ld: cannot find -lwayland-cursor /usr/bin/ld: cannot find -lxcb-xinerama /usr/bin/ld: cannot find -lXrender /usr/bin/ld: cannot find -lxcb-xkb /usr/bin/ld: cannot find -lxcb-sync /usr/bin/ld: cannot find -lxcb-xfixes /usr/bin/ld: cannot find -lxcb-randr /usr/bin/ld: cannot find -lxcb-image /usr/bin/ld: cannot find -lxcb-shm /usr/bin/ld: cannot find -lxcb-keysyms /usr/bin/ld: cannot find -lxcb-icccm /usr/bin/ld: cannot find -lxcb-shape /usr/bin/ld: cannot find -lxcb-glx /usr/bin/ld: cannot find -lXi /usr/bin/ld: cannot find -lSM /usr/bin/ld: cannot find -lICE /usr/bin/ld: cannot find -lxcb-render-util /usr/bin/ld: cannot find -lxcb-render /usr/bin/ld: cannot find -lxkbcommon-x11 /usr/bin/ld: cannot find -ljpeg /usr/bin/ld: cannot find -lmng /usr/bin/ld: cannot find -ltiff /usr/bin/ld: cannot find -lwebp /usr/bin/ld: cannot find -lwebpdemux /usr/bin/ld: cannot find -lgbm /usr/bin/ld: cannot find -ldrm /usr/bin/ld: cannot find -ldbus-1 /usr/bin/ld: cannot find -lXext /usr/bin/ld: cannot find -lmtdev /usr/bin/ld: cannot find -linput /usr/bin/ld: cannot find -lxkbcommon /usr/bin/ld: cannot find -lpng16 /usr/bin/ld: cannot find -lharfbuzz /usr/bin/ld: cannot find -ludev /usr/bin/ld: cannot find -licui18n /usr/bin/ld: cannot find -licuuc /usr/bin/ld: cannot find -licudata /opt/Qt5.8/lib/libQt5Core.a(qlibrary_unix.o): In function `QLibraryPrivate::load_sys()': qlibrary_unix.cpp:(.text+0x103a): warning: Using 'dlopen' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking /usr/bin/ld: cannot find -lpcre16 /usr/bin/ld: cannot find -lgthread-2.0 /usr/bin/ld: cannot find -lglib-2.0 /usr/bin/ld: cannot find -lxcb /usr/bin/ld: cannot find -lX11 /usr/bin/ld: cannot find -lX11-xcb /usr/bin/ld: cannot find -lfontconfig /usr/bin/ld: cannot find -lfreetype /usr/bin/ld: cannot find -lts /usr/bin/ld: cannot find -lEGL /usr/bin/ld: cannot find -lGL collect2: error: ld returned 1 exit status make: *** [Makefile:312: main] Error 1
Linking to Static Builds of Qt
The device-specific sysroots in Boot to Qt come with a dynamically linked version of Qt libraries ( *.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.
Requirements
In addition to installing Qt for Device Creation, ensure that required packages are installed for all Qt modules that are included in the static build. For more information, see Qt for Linux Requirements and Requirements for Development Host. Note that dependencies for the xcb platform plugin need not be installed, as Qt will be configured without xcb support. Install Qt sources by running the MaintenanceTool, located in the root of INSTALL_DIR . Alternatively, clone the qt5 repository using git.
Building Qt for Static Linking
To use static linking, Qt must be built with the -static configuration option. The following configure command selects the correct options and 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:
export SYSROOT_BASE=/5.9/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
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 Qt for Device Creation installation. Description of the used variables:
SYSROOT_BASE | Base directory for the sysroots (host and target) for the device |
TARGET_DEVICE | Target device (mkspec) |
SYSROOT_TARGET | Target sysroot directory under SYSROOT_BASE |
CROSSCOMPILE_PREFIX | Cross-compilation toolchain path and tool prefix (ends with ‘-‘) |
HOST_PREFIX | Location to install the host binaries (qmake, moc, rcc, etc.) |
cd ./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
Above, -prefix sets the intended destination of the Qt build on the device (sysroot). Running make install will, by default, install Qt under sysroot/prefix . Compiling in xcb support is disabled, OpenGL ES 2.0 support is selected, and Qt WebEngine is excluded from the build, as it does not support static builds. More information about configure options is available in the Qt for Embedded Linux documentation. If configuration is successful, proceed to build and install Qt:
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 QTPLUGIN variable.
After running qmake, the project directory contains a _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:
Alternatively, the automatic generation of Q_IMPORT_PLUGIN() macros can be turned off:
The relevant plugins then need to be explicitly imported in the application code.
Adding QML Imports
Similar to how Qt plugins are imported, qmake invokes the qmlimportscanner tool to scan the application’s .qml files, and generates a _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 QtQuick and QtQuick.Window import statements, the following statements are generated:
Q_IMPORT_PLUGIN(QtQuick2Plugin) Q_IMPORT_PLUGIN(QtQuick2WindowPlugin)
Available under certain Qt licenses.
Find out more.
Qt 6.2 static build (Linux). Статическая сборка Qt 6.2 (Ubuntu, Debian, Linux Mint)
или с официального сайта https://cmake.org/download/ При установке сайта через *.sh или из архива *.tar.gz необходимо создать ссылку на cmake из вашего каталога в каталог /usr/bin/:
2. Скачиваем архив исходников Qt для Linux (qt-everywhere-src-6.2.4.tar.xz) с официального сайта https://download.qt.io/official_releases/qt/6.2/6.2.4/single/qt-everywhere-src-6.2.4.tar.xz
3. Создаем каталог, например, «/home/user/Qt/Qt6.2.4-x64-linux-gcc-static/src/» и распаковываем в него содержимое архива исходников и переходим в него
2. Чтобы при ./configure не получить ошибку отсутствия libclangBasic.a устанавливаем:
./configure -platform linux-g++-64 -static -release -opensource -confirm-license -skip qtwebengine -prefix /home/user/qt/qt6.2.4-x64-linux-gcc-static
где 4 — число потоков для сборки. Ни в коем случае не используйте флаг —parallel без цифр, иначе получите бесконечный рост потребления памяти с последующим зависанием ОС.
Протестированные ОС: Ubuntu 20.04, Debian 11.2, Linux Mint 20.3, Linux Mint LMDE 5.0
Пункт 4 не выполняется — «Error: could not load cache».
Попытка запустить «cmake .» говорит, что нужен документ «CMakeLists.txt», взять который неоткуда.
Нипонятна. Но в целом инструкция хорошая.
З.Ы. После пункта 3 (конфигурации) консоль выводит подсказку о том, что теперь нужно просто запустить «gmake» и больше ничего не делать, однако сборка заканчивается с ошибкой («Error 2»). Отмечу, что в винде сборка статического Qt также заканчивается с ошибками, однако всё работает корректно. Нипонятна2.
Дополню предыдущий комментарий:
3. выполнить «./configure -platform linux-g++ -release -static -fontconfig -opensource -confirm-license» из каталога /src
4. выполнить «gmake»
Готово. Так работает. Не знаю, почему с указанной на этом сайте конфигурацией ничего не работает; возможно, указывать в конце (пункт 3) полный путь — ошибка, но кто знает.
Fedora 37
Пытаюсь собрать Qt6 — 6.4.0 из исходников.
При запуске ./configure выдает следующее:
Can’t locate English.pm in @INC (you may need to install the English module) (@INC
contains: /usr/local/lib64/perl5/5.36 /usr/local/share/perl5/5.36
/usr/lib64/perl5/vendor_perl /usr/share/perl5/vendor_perl /usr/lib64/perl5
/usr/share/perl5) at
/home/****/Development/Qt/Static/6.4.0/Src/qtbase/libexec/syncqt.pl line 19.