As the title suggest, the goal is successfully building the Qt framework and a Qt application in a way that produces a single executable binary with no external dependencies.
My motivation is that ever since the build system got "improved" in Qt 5.8, I wasn't really able to complete a successful static Qt build. And even before that, while building a static Qt framework was effortless, it didn't really produce an executable binary with no external dependencies. There was still a number of libraries that had to be bundled, and only Qt libraries got statically linked.
Going way back to the days before Qt 5.8, I was able to get a successful static Qt build via the following configuration:
configure -c++std c++11 -prefix E:\Qt\Qt58s -platform win32-g++ -release -opensource -static -qt-zlib -qt-libpng -qt-libjpeg -qt-freetype -no-compile-examples -no-icu -opengl desktop -skip qtscript -nomake examples -nomake tests -skip qtwayland -skip qtwebview -skip qtwebengine -skip qtwebchannel -no-qml-debug -confirm-license -L E:\msys64\mingw64\lib -qt-sql-psql -qt-sql-mysql -l mysqlclient -I E:\msys64\mingw64\include\mariadb
To summarize the configuration, it was limited to release builds, omitting any platform provided libraries and opting into using the ones that Qt bundles. Removing icu as a significant source of binary bloat, as well as tests and examples to cut build time short, and also the web engine, which doesn't build with GCC. Additionally, the configuration opts to include postgres and mysql driver support, the latter of which via the mariadb client library.
This build config as always succeeded for several minor versions of Qt 5, but it never really produced dependency-free executables. I still had to manually link psql and mysql libraries in the PRO file, and I still had to include at the very least the gcc runtime libs.
While it has been proven successful to link runtime libs statically by adding QMAKE_LFLAGS += -static-libgcc -static-libstdc++
to the PRO file, this only handled those particular libraries.
On the "grand scale", adding static linker flags via QMAKE_LFLAGS += -static
has never ever resulted in a successful build, instead resulting in linking errors and conflicts between different libs with internally link to the same libs.
But then again, then came Qt 5.8, which redesigned the build system configuration for the sake of improving it. And like many "improvements" it actually came in broken with no viable way to select third party libs in the config, instead having to manually hack various JSON configuration files.
Since then that bug has been fixed, leading me to resume my efforts to create a fully static Qt build. Now using the following configuration:
configure -prefix E:\Qt\Qt591s -c++std c++11 -platform win32-g++ -release -opensource -static -static-runtime -qt-zlib -qt-libpng -qt-libjpeg -qt-freetype -no-compile-examples -no-icu -opengl desktop -skip qtscript -nomake examples -nomake tests -skip qtwayland -skip qtwebview -skip qtwebengine -skip qtwebchannel -no-qml-debug -confirm-license -sql-psql -sql-mysql MYSQL_INCDIR=E:\msys64\mingw64\include\mariadb MYSQL_LIBDIR=E:\msys64\mingw64\lib MYSQL_LIBS="-l mysqlclient" -L E:\msys64\mingw64\lib
The difference is using the new syntax to specify 3rd party libs, and adding the -static-runtime
flag. Which later turned out to be the cause of a config fail, as mysql was failing to resolve indirect dependencies, which allegedly should work if the entire dependency tree is included explicitly.
Eager to get a working build, I simply omitted -static-runtime
, and indeed, I finally got a working config. But I wasn't quite there yet, as the build failed, with no meaningful output to signify why.
The next step was to try and limit the compilation output via using the -silent
configuration flag, which unfortunately resulted in a build fail 5 seconds in the compilation progress, revealing a long standing bug which prevented this flag from being used with GCC, regardless of whether you build Qt or a Qt application.
I next tried to build using a single thread in hope that I will get less output clutter and possibly even some insight into why the build is failing. Alas, to no avail. All I could take out of the output is that the build fails at the libjpg step. Which prompted me to remove all the flags specifying the usage of bundled libs, which got me through libjpg, only to have the build fail at the platform plugin, with just as little insight into why.
As a last resort, I tried removing most of the potentially problematic config flags, including the static build, in hopes to at least get a successful "regular build, which too has failed:
configure -prefix E:\Qt\ Qt591test -c++std c++11 -platform win32-g++ -release -opensource -no-compile-examples -no-icu -opengl desktop -skip qtscript -nomake examples -nomake tests -skip qtwayland -skip qtwebview -skip qtwebengine -skip qtwebchannel -no-qml-debug - confirm-license
Leaving me with the following output:
g++ -fno-keep-inline-dllexport -pipe -O2 -std=c++11 -fno-exceptions -Wex
tra -Wall -W -Wvla -Wdate-time -Wshift-overflow=2 -Wduplicated-cond -dM -E -o .m
oc\release\moc_predefs.h e:\share\qt-everywhere-opensource-src-5.9.1\qtbase\mksp
ecs\features\data\dummy.cpp
g++ -c -fno-keep-inline-dllexport -pipe -O2 -std=c++11 -fno-exceptions -
Wextra -Wall -W -Wvla -Wdate-time -Wshift-overflow=2 -Wduplicated-cond -DUNICODE
-DQT_NO_CAST_FROM_ASCII -DLIBEGL_NAME=libEGL -DLIBGLESV2_NAME=libGLESv2 -DQT_NO
_NARROWING_CONVERSIONS_IN_CONNECT -DQT_NO_EXCEPTIONS -DQT_NO_DEBUG -DQT_PLUGIN -
DQT_EVENTDISPATCHER_SUPPORT_LIB -DQT_ACCESSIBILITY_SUPPORT_LIB -DQT_FONTDATABASE
_SUPPORT_LIB -DQT_THEME_SUPPORT_LIB -DQT_GUI_LIB -DQT_CORE_LIB -IE:\share\qt-eve
rywhere-opensource-src-5.9.1\qtbase\src\plugins\platforms\direct2d -I. -IE:\shar
e\qt-everywhere-opensource-src-5.9.1\qtbase\src\plugins\platforms\windows -IE:\s
hare\qt-everywhere-opensource-src-5.9.1\qtbase\src\3rdparty\wintab -IE:\share\qt
-everywhere-opensource-src-5.9.1\qtbase\include -IE:\share\qt-everywhere-opensou
rce-src-5.9.1\qtbase\include\QtEventDispatcherSupport -IE:\share\qt-everywhere-o
pensource-src-5.9.1\qtbase\include\QtEventDispatcherSupport\5.9.1 -IE:\share\qt-
everywhere-opensource-src-5.9.1\qtbase\include\QtEventDispatcherSupport\5.9.1\Qt
EventDispatcherSupport -I..\..\..\..\include -I..\..\..\..\include\QtEventDispat
cherSupport -IE:\share\qt-everywhere-opensource-src-5.9.1\qtbase\include\QtAcces
sibilitySupport -IE:\share\qt-everywhere-opensource-src-5.9.1\qtbase\include\QtA
ccessibilitySupport\5.9.1 -IE:\share\qt-everywhere-opensource-src-5.9.1\qtbase\i
nclude\QtAccessibilitySupport\5.9.1\QtAccessibilitySupport -I..\..\..\..\include
\QtAccessibilitySupport -IE:\share\qt-everywhere-opensource-src-5.9.1\qtbase\inc
lude\QtFontDatabaseSupport -IE:\share\qt-everywhere-opensource-src-5.9.1\qtbase\
include\QtFontDatabaseSupport\5.9.1 -IE:\share\qt-everywhere-opensource-src-5.9.
1\qtbase\include\QtFontDatabaseSupport\5.9.1\QtFontDatabaseSupport -I..\..\..\..
\include\QtFontDatabaseSupport -IE:\share\qt-everywhere-opensource-src-5.9.1\qtb
ase\include\QtThemeSupport -IE:\share\qt-everywhere-opensource-src-5.9.1\qtbase\
include\QtThemeSupport\5.9.1 -IE:\share\qt-everywhere-opensource-src-5.9.1\qtbas
e\include\QtThemeSupport\5.9.1\QtThemeSupport -I..\..\..\..\include\QtThemeSuppo
rt -IE:\share\qt-everywhere-opensource-src-5.9.1\qtbase\include\QtGui\5.9.1 -IE:
\share\qt-everywhere-opensource-src-5.9.1\qtbase\include\QtGui\5.9.1\QtGui -I..\
..\..\..\include\QtGui\5.9.1 -I..\..\..\..\include\QtGui\5.9.1\QtGui -IE:\share\
qt-everywhere-opensource-src-5.9.1\qtbase\include\QtGui -I..\..\..\..\include\Qt
Gui -IE:\share\qt-everywhere-opensource-src-5.9.1\qtbase\include\QtCore\5.9.1 -I
E:\share\qt-everywhere-opensource-src-5.9.1\qtbase\include\QtCore\5.9.1\QtCore -
I..\..\..\..\include\QtCore\5.9.1 -I..\..\..\..\include\QtCore\5.9.1\QtCore -IE:
\share\qt-everywhere-opensource-src-5.9.1\qtbase\include\QtCore -I..\..\..\..\in
clude\QtCore -I.moc\release -IE:\share\qt-everywhere-opensource-src-5.9.1\qtbase
\mkspecs\win32-g++ -o .obj\release\moc_qwindowsdirect2dnativeinterface.o .moc\re
lease\moc_qwindowsdirect2dnativeinterface.cpp
g++ -Wl,-s -shared -Wl,-subsystem,windows -Wl,--out-implib,E:\tmpbuild\q
tbase\plugins\platforms\libqdirect2d.a -o ..\..\..\..\plugins\platforms\qdirect2
d.dll object_script.qdirect2d.Release -ldwmapi -ld2d1 -ld3d11 -ldwrite -lVersio
n -lwinspool -limm32 -lwinmm -loleaut32 -lshlwapi -lshell32 -LE:\tmpbuild\qtbase
\lib E:\tmpbuild\qtbase\lib\libQt5EventDispatcherSupport.a E:\tmpbuild\qtbase\li
b\libQt5AccessibilitySupport.a E:\tmpbuild\qtbase\lib\libQt5FontDatabaseSupport.
a -lole32 -ladvapi32 -luuid E:\tmpbuild\qtbase\lib\libqtfreetype.a E:\tmpbuild\q
tbase\lib\libqtlibpng.a -lz E:\tmpbuild\qtbase\lib\libQt5ThemeSupport.a -lglu32
-lopengl32 -lgdi32 -luser32 E:\tmpbuild\qtbase\lib\libQt5Gui.a E:\tmpbuild\qtbas
e\lib\libQt5Core.a .obj\release\qdirect2d_resource_res.o
windres -i qjpeg_resource.rc -o .obj\release\qjpeg_resource_res.o --incl
ude-dir=. -DUNICODE -DQT_NO_NARROWING_CONVERSIONS_IN_CONNECT -DQT_NO_EXCEPTIONS
-DQT_NO_DEBUG -DQT_PLUGIN -DQT_GUI_LIB -DQT_CORE_LIB
E:\tmpbuild\qtbase\bin\moc.exe -DUNICODE -DQT_NO_NARROWING_CONVERSIONS_I
N_CONNECT -DQT_NO_EXCEPTIONS -DQT_NO_DEBUG -DQT_PLUGIN -DQT_GUI_LIB -DQT_CORE_LI
B --include .moc/release/moc_predefs.h -IE:/share/qt-everywhere-opensource-src-5
.9.1/qtbase/mkspecs/win32-g++ -IE:/share/qt-everywhere-opensource-src-5.9.1/qtba
se/src/plugins/imageformats/jpeg -IE:/share/qt-everywhere-opensource-src-5.9.1/q
tbase/src/3rdparty/libjpeg -IE:/share/qt-everywhere-opensource-src-5.9.1/qtbase/
include/QtGui/5.9.1 -IE:/share/qt-everywhere-opensource-src-5.9.1/qtbase/include
/QtGui/5.9.1/QtGui -IE:/tmpbuild/qtbase/include/QtGui/5.9.1 -IE:/tmpbuild/qtbase
/include/QtGui/5.9.1/QtGui -IE:/share/qt-everywhere-opensource-src-5.9.1/qtbase/
include -IE:/share/qt-everywhere-opensource-src-5.9.1/qtbase/include/QtGui -IE:/
tmpbuild/qtbase/include -IE:/tmpbuild/qtbase/include/QtGui -IE:/share/qt-everywh
ere-opensource-src-5.9.1/qtbase/include/QtCore/5.9.1 -IE:/share/qt-everywhere-op
ensource-src-5.9.1/qtbase/include/QtCore/5.9.1/QtCore -IE:/tmpbuild/qtbase/inclu
de/QtCore/5.9.1 -IE:/tmpbuild/qtbase/include/QtCore/5.9.1/QtCore -IE:/share/qt-e
verywhere-opensource-src-5.9.1/qtbase/include/QtCore -IE:/tmpbuild/qtbase/includ
e/QtCore -I. -IE:/msys64/mingw64/include/c++/7.1.0 -IE:/msys64/mingw64/include/c
++/7.1.0/x86_64-w64-mingw32 -IE:/msys64/mingw64/include/c++/7.1.0/backward -IE:/
msys64/mingw64/lib/gcc/x86_64-w64-mingw32/7.1.0/include -IE:/msys64/mingw64/incl
ude -IE:/msys64/mingw64/lib/gcc/x86_64-w64-mingw32/7.1.0/include-fixed -IE:/msys
64/mingw64/x86_64-w64-mingw32/include E:\share\qt-everywhere-opensource-src-5.9.
1\qtbase\src\plugins\imageformats\jpeg\main.h -o .moc\release\moc_main.cpp
g++ -c -fno-keep-inline-dllexport -pipe -O2 -std=c++11 -fno-exceptions -
Wextra -Wall -W -Wvla -Wdate-time -Wshift-overflow=2 -Wduplicated-cond -DUNICODE
-DQT_NO_NARROWING_CONVERSIONS_IN_CONNECT -DQT_NO_EXCEPTIONS -DQT_NO_DEBUG -DQT_
PLUGIN -DQT_GUI_LIB -DQT_CORE_LIB -IE:\share\qt-everywhere-opensource-src-5.9.1\
qtbase\src\plugins\imageformats\jpeg -I. -IE:\share\qt-everywhere-opensource-src
-5.9.1\qtbase\src\3rdparty\libjpeg -IE:\share\qt-everywhere-opensource-src-5.9.1
\qtbase\include\QtGui\5.9.1 -IE:\share\qt-everywhere-opensource-src-5.9.1\qtbase
\include\QtGui\5.9.1\QtGui -I..\..\..\..\include\QtGui\5.9.1 -I..\..\..\..\inclu
de\QtGui\5.9.1\QtGui -IE:\share\qt-everywhere-opensource-src-5.9.1\qtbase\includ
e -IE:\share\qt-everywhere-opensource-src-5.9.1\qtbase\include\QtGui -I..\..\..\
..\include -I..\..\..\..\include\QtGui -IE:\share\qt-everywhere-opensource-src-5
.9.1\qtbase\include\QtCore\5.9.1 -IE:\share\qt-everywhere-opensource-src-5.9.1\q
tbase\include\QtCore\5.9.1\QtCore -I..\..\..\..\include\QtCore\5.9.1 -I..\..\..\
..\include\QtCore\5.9.1\QtCore -IE:\share\qt-everywhere-opensource-src-5.9.1\qtb
ase\include\QtCore -I..\..\..\..\include\QtCore -I.moc\release -IE:\share\qt-eve
rywhere-opensource-src-5.9.1\qtbase\mkspecs\win32-g++ -o .obj\release\moc_main.o
.moc\release\moc_main.cpp
g++ -Wl,-s -shared -Wl,-subsystem,windows -Wl,--out-implib,E:\tmpbuild\q
tbase\plugins\imageformats\libqjpeg.a -o ..\..\..\..\plugins\imageformats\qjpeg.
dll object_script.qjpeg.Release -lglu32 -lopengl32 -lgdi32 -luser32 -LE:\tmpbui
ld\qtbase\lib E:\tmpbuild\qtbase\lib\libQt5Gui.a E:\tmpbuild\qtbase\lib\libQt5Co
re.a .obj\release\qjpeg_resource_res.o
jom: E:\tmpbuild\qtbase\Makefile [sub-qmake-qmake-aux-pro-make_first] Error 2
jom: E:\tmpbuild\Makefile [module-qtbase-make_first] Error 2
At this point, I'd like to reiterate that prior to Qt 5.8 I've been getting successful builds over several releases using the same toolchain.
My primary development platform is windows, where I use MSYS2 as a build environment and primary toolchain, using GCC 5.3.0. I've also been using dev libs provided by MSYS2 for psql and mariadbclient to save on the need to build them myself. I also target android and linux, so the question applies to those 3 platforms. I do not target macos or ios, so while not directly beneficial to me as an OP, information on those platforms will likely be still usable to some.
So, anyone up to the challenge to guide news like me through the hardship of getting a truly, fully static Qt build?
I am currently struggling with the latest release, at this time that is 5.9.1, but this question should remain relevant for future versions as well, which may introduce their own quirks.
no meaningful output to signify why
=> please attach all the output, anyhow. And the compilation log which fails with an error is not including the command that failed (since you were running a parallel make chances are it's somewhere intermingled in the output, run a non-parallel make and grab the build error). – peppe-silent
being a no-go, I don't see a way of distilling output to what's meaningful. – dtech