4
votes

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.

1
Not an answer, but I'd strongly suggest to post this on the interest@ ML, which is read by the people who develop Qt's build system (and they usually reply). Also, you stated 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
@peppe I am somewhat at odds with mailing lists, but if you are a participant, please do feel free to post this alongside a link to the actual question. I assume someone, who is working on something of the scale of the Qt build system will have a SO account, or at the very least would be interested in having one. The output I have published here is what I could get out of a single threaded make, and I don't really see any usable information in it. And with -silent being a no-go, I don't see a way of distilling output to what's meaningful.dtech
Since I ran out of commenting space, my interest is application development, and not framework building masochism. So I am somewhat reluctant to invest substantial effort into something that shouldn't be an issue to begin with. It is really bothersome that after 3 years of success, it's been almost a full year I haven't been able to produce a successful static Qt build. Which begs the question, is the build system really being improved upon, or is it deliberately tailored into something unfriendly to static builds, judging by the Qt "legal FAQ" and its vague threats on the subjectdtech
Further elaborating on the "legal FAQ" - it is full of vague and ambiguous threats how static linking would be problematic under LGPL, stopping just short of making factually false statements, when in reality all that LGPL requires is the ability to relink an application against a different set of libraries. Which means object files should suffice. Of course, it is understandable that they discourage LGPL usage and convenient at that, for the sake of promoting more commercial license sales. So in that context, I have my reservations towards how helpful "digia" employees are allowed to be...dtech
I don't think there's anything to do with the licensing. I'ts just that the 5.8 rewrite of the configuration/build system has caused a huge number of regressions.peppe

1 Answers

3
votes

A month later I was able to make some progress, not quite where the OP title is, but nonetheless, I am now able to build Qt consistently, in static or dynamic configuration, with my custom SQL libs and working SQL.

The culprit was actually jom, which consistently fails at different parts depending on the configuration. I tried several versions, and they all failed. I tried a number of different, progressively more conservative configure options, I even tried the painfully slow single threaded build. All failed.

However, using mingw32-make works with a 100% success rate, I accidentally discovered that as a last resort attempt, after using jom for years, because it is allegedly faster. However, make also supports parallel builds using the same -j coreCount parameter, so fast Qt builds is still an option without jom.

I will come back and update this whenever I get more progress... the saga continues.