静态构建的可执行文件没有DLL依赖项?

时间:2016-03-14 14:34:02

标签: c++ qt dll qt-creator static-linking

目前,我已经有一个基于QT的GUI项目,而后者又依赖于几个依次使用DLL文件的库项目。为了在没有QT的情况下将GUI分发到任何PC,我之前已经使用QT Creator生成的可执行文件并将其放入包含相关DLL(例如Qt5Core.dll,Qt5Gui.dll等)的文件夹中。 现在我尝试通过QT构建静态源代码来生成一个独立的可执行文件 - 所以希望只是(让我们说)gui_project.exe本身可以在没有一小部分支持DLL文件的情况下发布。

现在我可以成功构建不同的项目并为GUI生成可执行文件(让我们称之为gui_project.exe),但是当我尝试运行它时,我告诉我我失踪了一个DLL文件:

  

"程序可以启动,因为您的计算机缺少Qt5ExtSerialPort1.dll。尝试重新安装程序以解决此问题。"

现在在gui_project.pro中,我以为我可以指向.lib文件而不是.dll文件。为了解决这个问题,第一个注释掉的行是我最初做的事情,而第二行则是我尝试修复的事情:

#CONFIG(release, debug|release): LIBS += ../ProcessingLib/release/ProcessingLib.lib ../XpsLib/release/XpsLib.lib -L../SerialPortLib/qextserialport/release -lQt5ExtSerialPort1 /DELAYLOAD:XpsLib.dll
CONFIG(release, debug|release): LIBS += ../ProcessingLib/release/ProcessingLib.lib ../XpsLib/release/XpsLib.lib ../SerialPortLib/qextserialport/release/Qt5ExtSerialPort1.lib /DELAYLOAD:XpsLib.dll

XpsLib是一个控制步进电机的小项目。

我不知道自己是否认为我可以完全取消(第三方,例如QT的)DLL,所以如果我弄错了,请直接告诉我。否则,非常感谢任何有关如何调试此问题的建议。

我试图在线研究这个话题,但我最后只是让自己感到困惑。另外,如果有帮助的话,我很乐意分享我的代码 - 但最初我会尽量不要膨胀我的帖子,希望我在调试方面错过了一些明显的东西。

我正在使用: QT Creator 3.6.0, QT源5.4.2,[我错误地认为它原来是5.4.1 ..] msvc2013_64

------ Update1 ------

我将要求AlexanderVX详细说明描述" -MT -MTd选项的部分"。因此,我正在修改我的帖子,以包含更多(并且希望!)相关信息:

我的主要gui_project.pro文件使用这些QT组件:

QT       += core gui script

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

(所以我希望我不会为QtQuick,QML和一些更复杂的库而烦恼)。我添加了基本库,以使静态构建工作:

CONFIG += static

我从源码(版本5.4.1)安装了QT到文件夹:

U:\QT\

为了制造& configure,我打开了Visual Studio 2013的工具," VS2013 x64 Native Tools命令提示符",并做了:

U:
cd\QT\5.4\src
nmake distclean
configure -release -static -nomake examples -opengl desktop
nmake

然后我去了我的项目:(导航到C:.. \ gui_project)

nmake clean
qmake -config release
nmake

但是重新读取configure命令的信息(以及AlexanderVX的建议),我猜测错过了我的configure命令中的一些标志。但是在命令行查看可用于配置的帮助,我找到的最接近-MT -MTd的选项是:

    -no-mtdev .......... Do not enable support for mtdev.
 +  -mtdev ............. Enable support for mtdev.

假设上述内容是相关的(-mtdev是默认值),我应该禁用吗?

我看到您通过QT创建者制作静态链接可执行文件的说明;但是(手指交叉)我希望我可以通过命令提示符来掌握它作为第一步。我确实有一个青铜'使用此许可证的支持级别; QT支持帮助我成功地从源代码静态构建QT,但也许我还没有完全理解相关的配置选项。

------ Update2 ------

我认为我的问题实际上是在配置我的项目以引入DLL(即插件,主要由QT提供)方面。根据Kuba Oder之前发布的链接,我发现了:

http://www.formortals.com/how-to-statically-link-qt-4/

更具体地说,尝试应用第3步,我将这些行添加到我的项目文件中:

#-------------------------------------------------
#
# Project created by QtCreator 2011-11-24T10:35:18
#
#-------------------------------------------------
QT       += core gui script

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

# Prevent MSVC 2013 complaining "Conversion from string literal loses const qualifier"
QMAKE_CXXFLAGS_RELEASE -= -Zc:strictStrings
# See: http://stackoverflow.com/a/28625430/2903608

TARGET = gui_project
TEMPLATE = app

# Needed for static building?
CONFIG += static

SOURCES += main.cpp \
    ...

HEADERS += mainwindow.h \
    ...

FORMS += \
    ... 

RESOURCES += \
    gui_project.qrc

static {

  # SO (http://stackoverflow.com/a/26777201/2903608) Suggest adding this to libs
  LIBS += -LU:/Qt/5.4/msvc2013_64/plugins/platforms/
  # (The above folder contains for instance qjpeg, a standard plug-in)
  # In a similar vein, let's add this folder which contains Qt5Guis .lib and .dll:
  LIBS += -LU:/Qt/5.4/Src/qtbase/lib/
  LIBS += -LU:/Qt/5.4/msvc2013_64/bin/

  # Relying upon: http://www.formortals.com/how-to-statically-link-qt-4/
  CONFIG += static
  QTPLUGIN += qt5gui Qt5Widgets Qt5ExtSerialPort1
  DEFINES += STATIC
  ...

我修改了我的main.cpp,两行之间的段落以三个/开头:

#include <QApplication>
#include <QSplashScreen>
#include "mainwindow.h"

/// Requirement for Static linking?
#include <QtPlugin>
Q_IMPORT_PLUGIN(qt5gui)
Q_IMPORT_PLUGIN(Qt5Widgets)
Q_IMPORT_PLUGIN(Qt5ExtSerialPort)
///

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);
    ...
    return app.exec();
}

不幸的是,我现在遇到了3个链接错误,每个我尝试使用的DLL都有错误:

main.obj : error LNK2019: unresolved external symbol "struct QStaticPlugin const __cdecl qt_static_plugin_qt5gui(void)" (?qt_static_plugin_qt5gui@@YA?BUQStaticPlugin@@XZ)
 referenced in function "public: __cdecl Staticqt5guiPluginInstance::Staticqt5guiPluginInstance(void)" (??0Staticqt5guiPluginInstance@@QEAA@XZ)

main.obj : error LNK2019: unresolved external symbol "struct QStaticPlugin const __cdecl qt_static_plugin_Qt5Widgets(void)" (?qt_static_plugin_Qt5Widgets@@YA?BUQStaticPlugin@@XZ)
 referenced in function "public: __cdecl StaticQt5WidgetsPluginInstance::StaticQt5WidgetsPluginInstance(void)" (??0StaticQt5WidgetsPluginInstance@@QEAA@XZ)

main.obj : error LNK2019: unresolved external symbol "struct QStaticPlugin const __cdecl qt_static_plugin_Qt5ExtSerialPort1(void)" (?qt_static_plugin_Qt5ExtSerialPort1@@YA?BUQStaticPlugin@@XZ) 
 referenced in function "public: __cdecl StaticQt5ExtSerialPort1PluginInstance::StaticQt5ExtSerialPort1PluginInstance(void)" (??0StaticQt5ExtSerialPort1PluginInstance@@QEAA@XZ)

release\gui_project.exe : fatal error LNK1120: 3 unresolved externals
NMAKE : fatal error U1077: '"C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\BIN\amd64\link.EXE"' : return code '0x460'
Stop.
NMAKE : fatal error U1077: '"C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\BIN\amd64\nmake.exe"' : return code '0x2'
Stop.

查看这3个链接器错误中的第一个,我认为这是一个配对/替换(?)Qt5Gui.dll和/与Qt5Gui.lib的问题。

检查我的系统,每个系统的绝对路径是:

U:\Qt\5.4\Src\qtbase\lib\Qt5Gui.lib
U:\Qt\5.4\msvc2013_64\bin\Qt5Gui.dll

但是不知怎的,我在某个地方做不到?

------ Update3 - 次要------

我意识到自己已被错误Qt5ExtSerialPort1,最后忘记了1。链接器错误虽然没有改变。

非常感谢您的帮助和耐心帮助我。

1 个答案:

答案 0 :(得分:0)

  

如何在没有Qt DLL依赖项的情况下构建静态Windows Qt可执行文件?

上面有小维基: Build Standalone Qt Application for Windows

我想补充一点,根据你的应用程序,可能还需要配置一些东西。我们也不想拖动Visual C++ Redistributable,因此我们使用-MT -MTd选项(而不是-MD -MDs)编译整个Qt和应用程序作为默认值。更新#1:

  • 对于Qt 5.3及更早版本:C:\ Qt \ 5.3 \ Src.64 \ qtbase \ mkspecs \ win32-msvc2013 \ qmake.conf - 用MT替换MD,因此MD和MDd都转换为MT和MTd(案例敏感)。
  • for Qt 5.5及更高版本:C:\ Qt \ 5.5 \ QtSourceCode \ qtbase \ mkspecs \ common \ msvc-desktop.conf - 用MT替换MD,因此MD和MDd都转换为MT和MTd(区分大小写)

我没有用Qt 5.4检查(上面的一个?)。

请注意您使用的编译器,以便应用适当的文件/设置以使运行时与您的可执行文件静态链接。

是的,使用静态构建的Qt可执行文件分发QML / QtQuick是一种痛苦,但仍然可以管理。基本上,您将QtQuick脚本的整个目录与可执行文件一起复制。

请注意,使用命令行工具构建静态链接的可执行文件更容易:qmake和jom。但是有一种方法可以为同一配置设置Qt Creator和Visual Studio。使用Qt Creator,您需要设置Qt Version及其相关Compiler Kit,然后设置switch your project to that specific Compiler Kit

因此,静态构建是可管理的,但取决于特定的应用程序需求。我同意上面的评论,并非一切都是直截了当的,但从几年前的经验来看,互联网上的信息有助于提升程度,再加上自己的努力。购买商业Qt许可证会更加成功:您获得Qt公司的支持,某些类型的许可证(我认为具有'Silver'支持级别及以上级别)意味着它们支持源代码中的自定义Qt构建。