首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >没有DLL依赖关系的静态可执行文件?

没有DLL依赖关系的静态可执行文件?
EN

Stack Overflow用户
提问于 2016-03-14 14:34:02
回答 1查看 2.5K关注 0票数 0

目前,我已经有了一个基于QT的GUI项目,它反过来又依赖于几个库项目,这些库项目依次使用DLL文件。为了将GUI分发给没有QT的任何PC,我以前使用了Qt5Core.dll生成的可执行文件,并将其放入包含相关DLL(如Qt5Core.dll、Qt5Gui.dll等)的文件夹中。现在,我正在尝试通过从源代码构建静态QT来生成一个独立的可执行文件--因此希望(假设) gui_project.exe本身能够在没有少量支持DLL文件的情况下得到分发。

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

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

现在在gui_project.pro中,我想我可以指向.lib文件而不是.dll文件。为了解决这个问题,注释掉了第一行,行是我最初是如何处理的,而第二行是我试图修复的:

代码语言:javascript
运行
复制
#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 3.6.0,QT源代码5.4.2,我误以为原来是5.4.1。msvc2013_64

- Update1

我将请AlexanderVX详细介绍描述"-MT -MTd选项“的部分。因此,我正在修改我的帖子,以包括更多(希望!)有关资料:

我的主gui_project.pro文件使用以下QT组件:

代码语言:javascript
运行
复制
QT       += core gui script

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

(希望我没有费心使用QtQuick、QML和一些涉及更多的库)。在基本库中,我添加了一条,以使静态构建工作:

代码语言:javascript
运行
复制
CONFIG += static

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

代码语言:javascript
运行
复制
U:\QT\

为了进行生成和配置,我打开了Visual 2013的工具"VS2013 x64本机工具命令提示符“,并做了如下操作:

代码语言:javascript
运行
复制
U:
cd\QT\5.4\src
nmake distclean
configure -release -static -nomake examples -opengl desktop
nmake

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

代码语言:javascript
运行
复制
nmake clean
qmake -config release
nmake

但是,重新阅读配置命令的信息(以及AlexanderVX的建议),我猜我的配置命令中遗漏了一些标志。但是,查看命令行中可用于配置的帮助,我发现最接近-MT -MTd选项的是:

代码语言:javascript
运行
复制
    -no-mtdev .......... Do not enable support for mtdev.
 +  -mtdev ............. Enable support for mtdev.

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

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

- Update2

我认为我的问题实际上是将我的项目配置为拉入DLL(即插件,主要由QT提供)。继库巴·奥德之前发布的链接之后,我偶然发现:

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

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

代码语言:javascript
运行
复制
#-------------------------------------------------
#
# 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,两行之间的段落以三个/开头:

代码语言:javascript
运行
复制
#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都有一个链接错误,我试图使用:

代码语言:javascript
运行
复制
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.

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

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

代码语言:javascript
运行
复制
U:\Qt\5.4\Src\qtbase\lib\Qt5Gui.lib
U:\Qt\5.4\msvc2013_64\bin\Qt5Gui.dll

但不知怎么的,我找不到什么地方吗?

- Update3 -小调-

我意识到我输入了Qt5ExtSerialPort1,最后忘记了1。但是链接器错误没有改变。

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

EN

回答 1

Stack Overflow用户

发布于 2016-03-15 06:13:48

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

上面有一些小维基:为Windows构建独立的Qt应用程序

我想补充的是,根据您的应用程序,可能需要配置更多的东西。我们也不想拖动Visual C++可再分发,因此我们编译整个Qt和应用程序,默认情况下使用-MT -MTd选项(而不是-MD -MDs)。更新1:

  • 对于QT5.3和更早版本: C:\Qt\5.3\Src.64\qtbase\mkspecs\win32-msvc2013\qmake.conf --用MT替换MD,这样MD和MDd都被转换为MT和MTd (区分大小写)。
  • 对于QT5.5及更高版本: C:\Qt\5.5\QtSourceCode\qtbase\mkspecs\common\msvc-desktop.conf --用MT替换MD,这样MD和MDd都被转换为MT和MTd (区分大小写)。

我没有检查QT5.4(以上之一?)。

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

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

请注意,使用命令行工具qmake和jom构建静态链接的可执行文件比较容易。但是有一种方法可以为相同的配置同时设置Qt和Visual。使用Qt,您需要设置Qt版本及其依赖的编译器工具包,然后设置将项目切换到特定的编译器工具包

因此,静态构建是可管理的,但取决于特定的应用程序需求。我同意上面的评论,并不是所有事情都很简单,但从几年前的经验来看,互联网上的信息帮助了程度,再加上一些自己的努力。为了在购买商业Qt许可证方面取得更大的成功:您得到了Qt的支持,某些类型的许可证(我想是“Silver”支持级别及以上)意味着它们支持来自源代码的自定义Qt构建。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/35990386

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档