构建真正、完全静态的 Qt 5 框架和应用程序(Qt 5.8 之后)

dte*_*ech 5 c++ qt static build qt5

正如标题所示,目标是成功构建 Qt 框架和 Qt 应用程序,从而生成没有外部依赖项的单个可执行二进制文件。

我的动机是,自从构建系统在 Qt 5.8 中得到“改进”后,我就无法真正完成成功的静态 Qt 构建。甚至在此之前,虽然构建静态 Qt 框架毫不费力,但它并没有真正生成没有外部依赖项的可执行二进制文件。仍然有许多库需要捆绑,并且只有 Qt 库进行了静态链接。

追溯到 Qt 5.8 之前的日子,我能够通过以下配置获得成功的静态 Qt 构建:

配置 -c++std c++11 -prefix E:\Qt\Qt58s -platform win32-g++ -release -opensource -static -qt-zlib -qt-libpng -qt-libjpeg -qt-freetype -no-compile-示例 -no-icu -opengl 桌面 -skip qtscript -nomake 示例 -nomake 测试 -skip qtwayland -skip qtwebview -skip qtwebengine -skip qtwebchannel -no-qml-debug -confirm-license -LE:\msys64\mingw64\lib -qt -sql-psql -qt-sql-mysql -l mysqlclient -IE:\msys64\mingw64\include\mariadb

总结一下配置,它仅限于发布版本,省略任何平台提供的库并选择使用 Qt 捆绑的库。删除了作为二进制膨胀的重要来源的 icu,以及缩短构建时间的测试和示例,以及不使用 GCC 构建的 Web 引擎。此外,配置选择包括 postgres 和 mysql 驱动程序支持,后者通过 mariadb 客户端库实现。

这个构建配置对于 Qt 5 的几个小版本来说总是成功的,但它从未真正生成无依赖的可执行文件。我仍然必须在 PRO 文件中手动链接 psql 和 mysql 库,并且我仍然必须至少包含 gcc 运行时库。

虽然已证明通过添加静态链接运行时库是成功的QMAKE_LFLAGS += -static-libgcc -static-libstdc++到 PRO 文件来静态链接运行时库是成功的,但这仅处理那些特定的库。

在“大规模”上,通过添加静态链接器标志QMAKE_LFLAGS += -static从未导致成功构建,而是导致内部链接到相同库的不同库之间的链接错误和冲突。

但话又说回来,Qt 5.8 重新设计了构建系统配置以进行改进。与许多“改进”一样,它实际上被破坏了,没有可行的方法在配置中选择第三方库,而必须手动破解各种 JSON 配置文件。

从那时起,该错误已得到修复,使我继续努力创建完全静态的 Qt 构建。现在使用以下配置:

配置 -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 示例 -nomake 测试 -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

不同之处在于使用新语法来指定第 3 方库,并添加标志-static-runtime。后来证明这是配置失败的原因,因为 mysql 无法解决间接依赖关系,据称如果显式包含整个依赖关系树,则应该可以工作。

渴望获得一个有效的构建,我只是省略了-static-runtime,事实上,我终于得到了一个有效的配置。但我还没有完全做到这一点,因为构建失败了,没有有意义的输出来表明原因。

下一步是尝试通过使用-silent配置标志来限制编译输出,不幸的是,这导致了编译过程中 5 秒的构建失败,揭示了一个长期存在的错误,该错误阻止了该标志与 GCC 一起使用,无论您是否构建 Qt 或 Qt 应用程序。

接下来,我尝试使用单线程进行构建,希望能够减少输出混乱,甚至可能了解构建失败的原因。唉,没有用。我能从输出中得到的只是构建在 libjpg 步骤失败。这促使我删除了所有指定捆绑库的使用的标志,这让我完成了 libjpg,但平台插件的构建失败了,而且对原因也了解甚少。

作为最后的手段,我尝试删除大多数可能有问题的配置标志,包括静态构建,希望至少获得成功的“常规构建”,但也失败了:

配置 -prefix E:\Qt\ Qt591test -c++std c++11 -platform win32-g++ -release -opensource -no-compile-examples -no-icu -opengl 桌面 -skip qtscript -nomake 示例 -nomake 测试 -跳过 qtwayland -跳过 qtwebview -跳过 qtwebengine -跳过 qtwebchannel -no-qml-debug - 确认许可证

给我留下以下输出:

        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
Run Code Online (Sandbox Code Playgroud)

在这一点上,我想重申,在 Qt 5.8 之前,我已经使用相同的工具链在多个版本中获得了成功的构建。

我的主要开发平台是Windows,我使用MSYS2作为构建环境和主要工具链,使用GCC 5.3.0。我还一直在使用 MSYS2 为 psql 和 mariadbclient 提供的开发库,以节省自己构建它们的需要。我还针对 android 和 linux,所以这个问题适用于这 3 个平台。我不以 Macos 或 ios 为目标,因此虽然作为 OP 对我没有直接好处,但这些平台上的信息可能仍然对某些人有用。

那么,有谁愿意像我一样接受挑战来引导新闻克服获得真正、完全静态的 Qt 构建的困难吗?

我目前正在努力使用最新版本,目前是 5.9.1,但这个问题也应该与未来的版本相关,这可能会引入他们自己的怪癖。

dte*_*ech 3

一个月后,我取得了一些进展,虽然不完全是 OP 标题所指的那样,但尽管如此,我现在能够使用我的自定义 SQL 库和工作 SQL 以静态或动态配置一致地构建 Qt。

罪魁祸首实际上是jom,它根据配置的不同在不同部分始终失败。我尝试了几个版本,但都失败了。我尝试了许多不同的、逐渐更加保守的配置选项,我什至尝试了极其缓慢的单线程构建。全部失败了。

然而,在使用成功率100%的作品时,我在使用多年mingw32-make后意外发现作为最后的尝试,因为据说它更快。jom然而,make也支持使用相同-j coreCount参数的并行构建,因此快速 Qt 构建仍然是一个没有jom.

每当我取得更多进展时,我都会回来更新……传奇仍在继续。