Qt静态链接和部署

80

我最近制作了一个简单的qt应用程序,现在想要将其部署(发布到公众)。但是我遇到了静态链接qt库的问题。

我按照qt文档上的指南重新构建了qt和我的应用程序,使它们可以静态链接。但是发布版本仍然需要qtgui / qtcore dll文件,原因不明,我想知道是否有人遇到过这种问题?或者更好的是,已经成功解决了这个问题?

http://doc.qtsoftware.com/4.5/deployment-windows.html


3
你是否有QtCore4.a和QtGui4.a的静态副本?如果有,加上CONFIG += static即可解决问题。如果没有Qt的静态副本,请下载源代码并进行编译。编译静态库需要几个小时的时间。 - Md. Minhazul Haque
7个回答

49

我写了如何进行静态链接的指南

以及如何使用多种编译器构建小型静态Qt库(因为针对简单程序,Qt库会变得非常大)。 你也可以查看BitRock安装程序,该程序对于开源项目是免费的。

简而言之,如果您正在使用Qt认为是插件的任何内容,例如大多数图像类型(JPEG、GIF)或数据库支持,则情况会变得更加复杂。 例如,如果您想要包含对Oracle DBMS和GIF图像的支持,您需要将以下内容添加到您的 .PRO 文件中:

QTPLUGIN += qsqloci qgif
CONFIG += static

您需要完成以下步骤:

#include <QtPlugin>

在你的项目中,导入任何使用过的插件。为了使它能够再次通过动态链接编译(例如调试或添加功能时),你需要将这些设置更改回来,尽管这可以很容易地自动化。当构建用于静态链接的Qt库时也需要考虑一些因素,但Qt的指令至少会让你有所启发。


18
如果你使用静态链接,要注意许可问题。 - Lisa
4
以下是 Wayback Machine 的链接。第一个链接是有关将 Qt4 静态链接到应用程序的文章。第二个链接是有关构建更小并能够进行静态链接的 Qt 的文章。http://web.archive.org/web/20120729010312/http://www.formortals.com/how-to-statically-link-qt-4http://web.archive.org/web/20120723142656/http://www.formortals.com/build-qt-static-small-microsoft-intel-gcc-compiler - EMPraptor
3
你会很高兴知道链接已经恢复了。 - Charles Burns
@CharlesBurns,嗯,又坏了? - FRD
1
@Oshada http://doc.qt.io/QtForDeviceCreation/qtee-static-linking.html 是当前的官方文档。 - Charles Burns
显示剩余6条评论

24

使用Qt 5.5很简单。在构建Qt之前,你需要运行configure脚本。以下是传递给configure的设置:

  1. 你想要静态Qt库吗?

应该向configure传递-static选项

  1. 您是否希望构建Qt及您的应用程序使用静态C ++运行时?

应该向configure传递-static-runtime选项

  1. 你想要XP目标吗?

应该向configure传递-target xp选项

此外,请按照这篇博客文章的说明操作。

至少到v.3.5.0,Qt Creator不会自动支持XP目标,因为它没有正确设置构建工具的环境。你必须按照博客文章的要求手动修改构建环境。


9
此外,请注意您的静态构建仍将动态链接到Visual Studio运行时!请参见此常见问题解答互联网档案馆链接,以防链接失效)。
为什么静态构建的Qt使用动态的Visual Studio运行库?我需要部署它们到我的应用程序吗?
Qt是使用-MD(d)开关构建的,该开关链接到动态C/C++运行时库。这是必要的,因为我们在使用除了-MD(d)标志以外的任何东西时都会遇到内存问题,并且通常建议使用该标志。您不应该自己更改此标志以供应用程序使用,因为如果将标志更改为-MT,则会与Qt库的构建方式产生冲突。您也不应该为Qt更改它,因为这可能会导致问题。
当使用-static选项时,Qt仍然是静态构建的,这意味着在部署应用程序时,您不需要分发Qt dlls。但是,您将不得不分发C运行时(如果它们不存在于目标计算机上),请参阅我们的部署文档http://doc.qt.io/qt-5/windows-deployment.html#application-dependencies

4

msys2提供了预构建的静态Qt5包

例如pacman -S mingw-w64-qt5-static

目前,为了静态链接Qt的所有依赖项,需要在使用CMake之前添加:
list(PREPEND CMAKE_FIND_LIBRARY_SUFFIXES .a .lib)
然后调用find_package(Qt5


CMAKE_AUTOSTATICPLUGINS已被新的上游实现替换,不再需要。


我想使用它,但我不确定如何设置CMAKE_AUTOSTATICPLUGINS。我正在使用qmake然后进行make编译。你能给予建议吗? - tofutim
你是不是打错了 qmake?因为这里是关于CMake的。你可以在全局设置中简单地设置它:set(CMAKE_AUTOSTATICPLUGINS ON)或者作为一个目标特定属性进行设置:set_target_properties(${PROJECT_NAME} PROPERTIES AUTOSTATICPLUGINS ON) - Darklighter

3

我是一名有用的助手,可以为您进行文本翻译。

我刚刚使用QT插件(5.9)和VS(2015)(Win)进行了应用程序的静态编译(Debug)。

a)将以下代码添加到您的代码中。

#include <QtPlugin>
Q_IMPORT_PLUGIN (QWindowsIntegrationPlugin);
b) 将以下内容添加到链接路径中
\5.9.0_x86_static_install\lib
\5.9.0_x86_static_install\bin
\5.9.0_x86_static_install\plugins
\5.9.0_x86_static_install\plugins\platforms
\5.9.0_x86_static_install\plugins\imageformats

c) 将QT静态库和内部VS库的列表添加到链接列表中。

version.lib
imm32.lib
shlwapi.lib
rpcrt4.lib
Ws2_32.lib
Mpr.lib
Netapi32.lib
Rpcrt4.lib
Iphlpapi.lib
winmm.lib
gdi32.lib
advapi32.lib
msimg32.lib
UxTheme.lib
translatord.lib
preprocessord.lib
d3d9.lib
dxguid.lib
libEGLd.lib
libGLESv2d.lib
iphlpapi.lib
psapi.lib
ws2_32.lib
Dwmapi.lib
Qt5CoreD.lib
Qt5Guid.lib
Qt5Xmld.lib
Qt5Widgetsd.lib
Qt5Networkd.lib
Qt5Winextrasd.lib
Qt5PlatformCompositorSupportd.lib
qicod.lib
qtmaind.lib
qtlibpngd.lib
qtharfbuzzd.lib
qtpcre2d.lib
qwindowsd.lib
Qt5FontDatabaseSupportd.lib
Qt5ThemeSupportd.lib
Qt5EventDispatcherSupportd.lib
Qt5AccessibilitySupportd.lib
qtfreetyped.lib

凯文·希金斯

太好了,这对我很有帮助。我在这里缺少你提到的一个 .lib 文件,导致出现了链接错误。非常感谢。 - user2095932
嘿,Kevin!谢谢分享!请问您使用了什么配置来进行静态链接的qt构建?我进入了Src文件夹并执行了:“configure -platform win32-msvc -static -release -nomake examples -nomake tests -opensource”,我还注意到在您的答案中,您链接的库是调试版本的,所以我当然改成了发布版本,但仍然出现链接错误。我想我需要重新构建qt并尝试构建调试和发布版本。 - user7867434

3

我建议您使用linuxdeployqt这个工具。它可以帮助解决大部分依赖问题。我使用它成功地打包了我的Qt应用程序。


1
linuxdeployqt需要旧版本的Linux才能运行,这会安装旧版本的glibc。我的所有Linux环境都无法使用它。 - 0xAA55

1
这个答案适用于在Windows上使用MSYS2和mingw-w64编译器以及qmake。QT版本为5.15.0。
安装包qt5-static会为您提供一个QT的构建版本,生成的可执行文件不依赖于任何QT DLLs。(示例命令行- pacman -Ss mingw64/mingw-w64-x86_64-qt5-static)
然而,在这里引入了一个新问题:它没有将-static标志传递给gcc。这意味着虽然可执行文件不依赖于QT DLLs,但它确实依赖于libgcc-s、libwinpthread.dll等。
通常,使用CONFIG += static来解决这个问题,这会导致qmake将-static传递给gcc。然而,正如其他答案中所指出的那样,对于qt-static构建,该配置选项被忽略了!
为了解决这个问题,我不得不在qmake文件中手动指定静态链接的gcc标志,即:
QMAKE_CXXFLAGS += -static
QMAKE_LFLAGS_WINDOWS += -static

这将导致一个(大型)二进制文件,除了 Windows 系统 DLL 之外没有任何外部依赖项。
(如果重要的话:我的用例是构建一个不应具有外部依赖项的 COM 进程服务器 DLL;我还使用了 TEMPLATE=lib 和 CONFIG += dll)。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接