At the moment, I've got a project with a QT-based GUI, which in turn relies upon a couple of library projects that use DLL files in turn. To distribute the GUI to any PC without QT, I've previously taken the executable that QT Creator generates and put it into a folder containing the relevant DLLs (such as Qt5Core.dll, Qt5Gui.dll, etc). Now I'm trying through QT built static from source to generate a standalone executable - so hopefully just (let's say) gui_project.exe itself can be distributed without a small host of supporting DLL files.
Now I can build the different projects successfully and generate the executable for the GUI (let's call it gui_project.exe), but when I try to run it I'm told I'm missing a DLL file:
"The program can start because Qt5ExtSerialPort1.dll is missing from your computer. Try reinstalling the program to fix this problem."
Now within gui_project.pro, I thought I could point to the .lib file instead of the .dll file. To address this the first, commented out, line is how I did things originally, whereas the second line is my attempt to fix things:
#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 is a small project controlling a stepper motor.
I don't know whether I'm deluding myself in thinking I can do away completely with (third-party, e.g. QT's) DLLs, so please put me straight if I got that wrong. Otherwise, any advice on how to debug this problem would be greatly appreciated.
I have tried to research the topic online but I only ended up confusing myself. Also, I'm happy to share my code if that helps - but initially I'll try not to bloat my post as hopefully I've missed something obvious in terms of debugging.
I am using: QT Creator 3.6.0, QT source 5.4.2, [I mistakenly thought it was 5.4.1 originally..] msvc2013_64
------ Update1 ------
I'm going to ask AlexanderVX to elaborate on the section describing the "-MT -MTd options". Thus I'm amending my post to include more (and hopefully!) relevant information:
My main, gui_project.pro file uses these QT components:
QT += core gui script
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
(So hopefully I've not bother with QtQuick, QML and some of the more involved libraries). Onto the basic libraries, I have added, to get static building working:
CONFIG += static
I installed QT from source (version 5.4.1), to the folder:
U:\QT\
In order to make & configure, I opened Visual Studio 2013's tool, "VS2013 x64 Native Tools Command Prompt", and did:
U:
cd\QT\5.4\src
nmake distclean
configure -release -static -nomake examples -opengl desktop
nmake
Then I went to my project: (Navigated to C:..\gui_project)
nmake clean
qmake -config release
nmake
But rereading the information on the configure command (and with AlexanderVX's advice), I'm guessing out missed some flag(s) from my configure command. But looking at the help available for configure at the command line, the closest to -MT -MTd options that I find is:
-no-mtdev .......... Do not enable support for mtdev.
+ -mtdev ............. Enable support for mtdev.
Assuming the above is relevant (-mtdev being the default), should I disable it?
I see your instructions for making statically linked executables made through QT creator; but (fingers crossed) I'm hoping I can master it through the command prompt as an initial step. I do have a 'Bronze' support level with this licence; QT support have helped me to successfully statically build QT from source, but perhaps I have not yet fully appreciated the relevant configuration option(s).
------ Update2 ------
I think my problem is actually in terms of the configuring my project to pull in DLLs (i.e. plug-ins, mostly provided by QT). Following the link that Kuba Oder posted previously, I came across:
http://www.formortals.com/how-to-statically-link-qt-4/
More specifically, trying to apply Step 3, I've add these lines to my project file:
#-------------------------------------------------
#
# 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
...
And I've modified my main.cpp, with the paragraph between the two lines beginning with three /
's:
#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();
}
Unfortunately, I'm now stuck with 3 linking errors, one for each DLL that I'm trying to use:
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.
Looking at the first of those 3 linker errors, I think it's a problem of pairing/substituting(?) Qt5Gui.dll and/with Qt5Gui.lib.
Examining my system, the absolute path for each is:
U:\Qt\5.4\Src\qtbase\lib\Qt5Gui.lib
U:\Qt\5.4\msvc2013_64\bin\Qt5Gui.dll
But somehow, I fall short somewhere?
------ Update3 - Minor ------
I realised I had typoed Qt5ExtSerialPort1
, forgetting the 1
at the end. Linker errors unchanged though.
Many thanks for your assistance and patience in helping me.