Qt 3rd Party Library Static Linking (QtSerialPort) - c++

Turns out static linking was working, but only for Qt libraries. My 3rd party library QtSerialPort is not linking statically. After some reasearch, I've found that I either have to build this library statically or I have to link directly to a .pri file in my .pro file.
I'm not sure how to do either since it seems QtSerialPort has not been designed for static linking.
The .pri method I really don't understand and has been vaguely described in these two links:
http://qt-project.org/forums/viewthread/15223
http://www.qtcentre.org/archive/index.php/t-54505.html
Does anyone have any adivce on how to get either of these methods to work? Or possibly another method?
Also, MSVCP100.dll is not linking statically if anyone could give me any advice on that.
==================================================================================
I am trying to get Qt to statically link libraries so that I can make a standalone application. I have followed various tutorials on how to build Qt statically then building a static application but I am not having much luck. I believe I have succesfully built Qt with static linking because the application has grown in size from 79KB to 7+MB but I am still getting errors saying QtCore4.dll and QtSerialPort.dll are missing. Also, another issue I'm having when using this static configuration, which isn't too serious, is that when I close my program Windows thinks it has crashed and gives me a window saying MyProgram.exe has stopped working...
I am on a Windows machine using MSVC 2010 with Qt 4.8.5 and am using the third party library QtSerialPort.
What I've done accoring to the guides I've been reading is:
Download and extract qt-everywhere-opensource-src-4.8.5.zip
Open /mkspec/mwin32-msvc2010/qmake.conf and change the follwing lines to
CONFIG += qt warn_on release incremental flat link_prl precompile_header autogen_precompile_source copy_dir_files debug_and_release debug_and_release_target
and
QMAKE_CLFAGS_RELEASE = -O2 -MT
I then open the MSVC2010 command prompt and cd to this . I then enter the commands
configure -static -release -platform win32-msvc2010
nmake sub-src
After this is done I open my project and add
CONFIG += static
to the .pro file. In QtCreator I then go into Projects, Manage Kits then to Qt Versions and browse to the qMake I just generated. I add a new Kit with this version of qMake. I then clean all and switch to this new kit and run qmake from QtCreator. I then use msvc2010 command prompt to go to the directory where the files are generated and then
nmake release
This generates a rather large .exe but like I said, it's still depending on a couple .dll's.

For static linking of external library one have a couple options, both have their pros and cons.
I. Compile the library for static linking yourself. Link to it.
Look for possible existing configuration switches for static linking. There can be something like QTSERIALPORT_STATIC = no, etc. in the library's .pro/.pri files. Just say yes for the library to compile for static linking and go to the step 4!
In .pro/.pri file replace CONFIG += dll with CONFIG += static.
Remove export declarations from the library. Typically Qt library symbols are declared with some definition like QTSERIALPORT_EXPORT which expands to Q_DECL_EXPORT/Q_DECL_IMPORT in shared library build / its header files usage when linking. You'll need to find where this QTSERIALPORT_EXPORT is defined and replace it with empty definition:
#define QTSERIALPORT_EXPORT // in source file
or
DEFINES += QTSERIALPORT_EXPORT # in .pro/.pri file
Build the library.
Link to the library .lib/.a file, use the library header files for symbol declarations in your project.
II. Include the library source files into your project and compile them within it (no linking at all).
Include all the source files of the library into your project (add to SOURCES in qmake project file)
Determine all the stuff the library depends on (other libraries, Qt options, etc.) and include it also into your .pro file.
OR
Include the proper .pri file into your .pro if the library author provides it for in-project compilation (i.e. include(QtSerialPort.pri) or something.)
Remove export/import declarations from the library source code — as described in the item 3 of part I.
Build your project.

Related

Adding static library link line to my Qt project file makes no difference

I've read a lot of "duplicate" posts on the subject of statically linking your Qt project on windows to statically built Qt core libs. However, I was left very confused when I compared it to what I am seeing. What I gathered from all the posts is if you already have the statically built Qt libs (which I seem to have here C:\Qt\5.4\mingw491_32\lib) all you need to do is to include a line like so
LIBS += -LC:/Qt/5.4/mingw491_32/lib -lQt5Core -lQtGui
in your .pro file without having to specify -static anywhere. However, this line seems to do exactly ZERO. When I comment it out my project builds exactly the same way without it. The exe is the same size and when I try to run it from command prompt a runtime error appears in a dialog box saying it can't find Qt5Core.dll. Its clearly still linking dynamically. What am I doing wrong? Here is the whole .pro file.
#QT +=
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = testproj
TEMPLATE = app
SOURCES += main.cpp mainwindow.cpp
HEADERS += mainwindow.h
FORMS += mainwindow.ui
QMAKE_CXXFLAGS +=-std=c++11
#LIBS += -LC:/Qt/5.4/mingw491_32/lib -lQt5Core
I clearly have major holes in my understanding of how Qt linking works on windows. Any help on this topic is highly appreciated.
Qt does not distribute static builds.
It seems you only have a dynamic build and got confused by the .lib/.a files. On Windows, there are 3 types of library:
Dynamic libraries (.dll)
Static libraries (.a or .lib depending on the toolchain)
Import libraries (.a or .lib depending on the toolchain)
Import libraries are only used with dynamic libraries. The import libraries are used by the linker when generating the exe, while the dynamic libraries are used at run time.
So if you have Qt5Core.lib or Qt5Core.a does not mean you have a static build of Qt.
To build your own static version of Qt, I suggest your read Building a static Qt for Windows using MinGW on Qt's wiki.
The major hint is: no matter how Qt is built, you shouldn't need to change anything in the project that uses Qt. Qmake and the configuration files in a given Qt install govern how the applications that use Qt are linked against Qt.
Another hint: a given Qt installation can be either configured for static or dynamic linking, not both. Thus any sort of configuration on the project end is superfluous: a given Qt install already "knows" how to link Qt correctly.
Any given .pro file should work whether Qt is linked statically or dynamically. You should not have any static-linking-specific entries. Remove the LIBS line from the project.
If your executable is dynamically linked, the only reason is that you're using a dynamically linked build of Qt. You should make a static build yourself first, and then use it with your project, and your executable will be statically linked against Qt. It's that simple.
Qt Creator doesn't care about these details either. All it does is invoke qmake and then the make tool. But each qmake is specific to a particular installation of Qt, and that qmake is configured to access that installation's configuration files, and those files contain the data needed to select the proper linking etc. So all of the information is specific to a particular kit one is using, and specifically to the Qt "version" that kit is using (really, a Qt installation because there can be multiple installs of the same version, configured differently).

Build static linked app with Qt5 on Windows [duplicate]

I am trying to deploy(release to public) a simple qt application I made recently, but got stuck at static linking qt libs.
I followed the guide on qt docs to re-build qt and my app statically. But the release build still require qtgui / qtcore dll for no apparent reasons, I wonder if anyone has seen this kind of problems before ? Or even better, has successfully resolved it ?
http://doc.qtsoftware.com/4.5/deployment-windows.html
I wrote a guide to static linking
and
How to build Qt static with multiple compilers and keep it small
(because it can get pretty big, especially for simple programs).
You may also want to check out the BitRock installer, which is free for open source projects.
In short, it turns out to be a little more complex if you are using anything Qt thinks of as a plugin, such as support for most image types (JPEG, GIF) or databases.
For example, if you want to include support for Oracle DBMS and GIF images for your icons, you add the following to your .PRO file:
QTPLUGIN += qsqloci qgif
CONFIG += static
You will then need to:
#include <QtPlugin>
in your project, and import any plugins used. You need to change these settings back order to get it to compile with dynamic linking again (like when debugging or adding features), though this can be easily automated. There are also considerations when building the Qt libraries for use with static linking, though the Qt instructions will at least get you started.
With Qt 5.5, things are quite easy. There's the configure script you have to run before building Qt. There are following orthogonal settings that you pass to configure:
Do you want a static Qt library?
-static option should be passed to configure
Do you want the build of Qt, and of your application, to use a static C++ runtime?
-static-runtime option should be passed to configure
Do you want XP targeting?
-target xp option should be passed to configure
Additionally, follow the instructions from this blog post.
Qt Creator didn't support XP targeting automagically at least until v.3.5.0 since it doesn't set up the environment for the build tools properly. You have to modify the build environment manually per the blog post.
Also, be aware that your static build will still link to the visual studio runtimes dynamically!
See this faq (internet archive link, in case the link goes away) :
Why does a statically built Qt use the dynamic Visual Studio runtime libraries ? Do I need to deploy those with my application ?
Qt is built using the -MD(d) switch, which links against the dynamic C/C++ runtime libraries. This is necessary as we have experienced memory problems when using anything but the -MD(d) flag, and in general, it is recommended to use. You should not alter this flag yourself for your application, because it conflicts with how the Qt library is built if you change the flag to -MT. You should not change it for Qt either, since it is likely to cause problems.
Qt is still built statically when using the -static option though, meaning you do not need to distribute the Qt dlls when deploying your application. You will have to distribute the C runtimes though (if they don't already exist on the target machine), see our deployment documentation http://doc.qt.io/qt-5/windows-deployment.html#application-dependencies.
msys2 has a pre-built static Qt5 package
e.g. pacman -S mingw-w64-qt5-static
Currently, to also get all dependencies of Qt statically linked, with CMake, you need to add:
list(PREPEND CMAKE_FIND_LIBRARY_SUFFIXES .a .lib)
before calling find_package(Qt5…
CMAKE_AUTOSTATICPLUGINS was replaced by a new upstream implementation and is not needed anymore.
I just compiled an application statically (Debug)
with QT Plugins(5.9),
with VS (2015) (Win).
a) Add to your code.
#include <QtPlugin>
Q_IMPORT_PLUGIN (QWindowsIntegrationPlugin);
b) Add the following to the link paths
\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) Add the list of QT static libraries and internal VS libraries to your link list.
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
Kevin Higgins
I recommend you to use linuxdeployqt this tool. It can help solve most of the dependency problems. And I use it to package my qt application successfully.
This answer applies to using MSYS2 with mingw-w64 as the compiler, in Windows, and qmake. The QT version is 5.15.0.
Installing the package qt5-static gives you a build of QT that produces executables who don't rely on any QT DLLs. (Example commandline - pacman -Ss mingw64/mingw-w64-x86_64-qt5-static).
However a new problem is introduced here: it does not pass the -static flag to gcc. Meaning that although the executable does not depend on QT DLLs, it does depend on libgcc-s, libwinpthread.dll etc.
Normally, this problem would be fixed by using CONFIG += static which causes qmake to pass -static to gcc. However, and as noted in the other answers, for a qt-static build that config option is ignored!
To solve this I had to manually specify the gcc flags for static linking in the qmake file, i.e. :
QMAKE_CXXFLAGS += -static
QMAKE_LFLAGS_WINDOWS += -static
Which results in a (large) binary with no external dependencies other than Windows system DLLs.
(In case it matters: my use case was building a COM in-process server DLL that should have no external dependencies; I was also using TEMPLATE=lib and CONFIG += dll).

Static linking in Windows [duplicate]

I am trying to deploy(release to public) a simple qt application I made recently, but got stuck at static linking qt libs.
I followed the guide on qt docs to re-build qt and my app statically. But the release build still require qtgui / qtcore dll for no apparent reasons, I wonder if anyone has seen this kind of problems before ? Or even better, has successfully resolved it ?
http://doc.qtsoftware.com/4.5/deployment-windows.html
I wrote a guide to static linking
and
How to build Qt static with multiple compilers and keep it small
(because it can get pretty big, especially for simple programs).
You may also want to check out the BitRock installer, which is free for open source projects.
In short, it turns out to be a little more complex if you are using anything Qt thinks of as a plugin, such as support for most image types (JPEG, GIF) or databases.
For example, if you want to include support for Oracle DBMS and GIF images for your icons, you add the following to your .PRO file:
QTPLUGIN += qsqloci qgif
CONFIG += static
You will then need to:
#include <QtPlugin>
in your project, and import any plugins used. You need to change these settings back order to get it to compile with dynamic linking again (like when debugging or adding features), though this can be easily automated. There are also considerations when building the Qt libraries for use with static linking, though the Qt instructions will at least get you started.
With Qt 5.5, things are quite easy. There's the configure script you have to run before building Qt. There are following orthogonal settings that you pass to configure:
Do you want a static Qt library?
-static option should be passed to configure
Do you want the build of Qt, and of your application, to use a static C++ runtime?
-static-runtime option should be passed to configure
Do you want XP targeting?
-target xp option should be passed to configure
Additionally, follow the instructions from this blog post.
Qt Creator didn't support XP targeting automagically at least until v.3.5.0 since it doesn't set up the environment for the build tools properly. You have to modify the build environment manually per the blog post.
Also, be aware that your static build will still link to the visual studio runtimes dynamically!
See this faq (internet archive link, in case the link goes away) :
Why does a statically built Qt use the dynamic Visual Studio runtime libraries ? Do I need to deploy those with my application ?
Qt is built using the -MD(d) switch, which links against the dynamic C/C++ runtime libraries. This is necessary as we have experienced memory problems when using anything but the -MD(d) flag, and in general, it is recommended to use. You should not alter this flag yourself for your application, because it conflicts with how the Qt library is built if you change the flag to -MT. You should not change it for Qt either, since it is likely to cause problems.
Qt is still built statically when using the -static option though, meaning you do not need to distribute the Qt dlls when deploying your application. You will have to distribute the C runtimes though (if they don't already exist on the target machine), see our deployment documentation http://doc.qt.io/qt-5/windows-deployment.html#application-dependencies.
msys2 has a pre-built static Qt5 package
e.g. pacman -S mingw-w64-qt5-static
Currently, to also get all dependencies of Qt statically linked, with CMake, you need to add:
list(PREPEND CMAKE_FIND_LIBRARY_SUFFIXES .a .lib)
before calling find_package(Qt5…
CMAKE_AUTOSTATICPLUGINS was replaced by a new upstream implementation and is not needed anymore.
I just compiled an application statically (Debug)
with QT Plugins(5.9),
with VS (2015) (Win).
a) Add to your code.
#include <QtPlugin>
Q_IMPORT_PLUGIN (QWindowsIntegrationPlugin);
b) Add the following to the link paths
\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) Add the list of QT static libraries and internal VS libraries to your link list.
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
Kevin Higgins
I recommend you to use linuxdeployqt this tool. It can help solve most of the dependency problems. And I use it to package my qt application successfully.
This answer applies to using MSYS2 with mingw-w64 as the compiler, in Windows, and qmake. The QT version is 5.15.0.
Installing the package qt5-static gives you a build of QT that produces executables who don't rely on any QT DLLs. (Example commandline - pacman -Ss mingw64/mingw-w64-x86_64-qt5-static).
However a new problem is introduced here: it does not pass the -static flag to gcc. Meaning that although the executable does not depend on QT DLLs, it does depend on libgcc-s, libwinpthread.dll etc.
Normally, this problem would be fixed by using CONFIG += static which causes qmake to pass -static to gcc. However, and as noted in the other answers, for a qt-static build that config option is ignored!
To solve this I had to manually specify the gcc flags for static linking in the qmake file, i.e. :
QMAKE_CXXFLAGS += -static
QMAKE_LFLAGS_WINDOWS += -static
Which results in a (large) binary with no external dependencies other than Windows system DLLs.
(In case it matters: my use case was building a COM in-process server DLL that should have no external dependencies; I was also using TEMPLATE=lib and CONFIG += dll).

QtCreator - use static dll lib

I want to make my app without any dependancies for the users. It works well when I put the dll files into the same folder as my exe.
I'm trying to set all those libraries to static use the following code in my pro file (Qt 4.8.1):
QMAKE_LFLAGS += -static-libgcc
CONFIG += static
The previous code doesn't change anything.
Here are the dll file I have included into my project folder:
libgcc_s_dw2-1.dll
mingwm10.dll
QtCore4.dll
QtGui4.dll
The fact is I don't want my app be more than a file and I don't want the users to download libs files, which are heavy (9mB for the last one).
Is there a way to compile a Qt project and use static libs?
I've tried to read some tutorials I've found on the Internet but they are all outdated. For what I read too, the solution would be to rebuild the Qt source code staticaly.
To be able to fully statically compile against Qt you need to rebuild the framework as static, using the pre-compiled framework isn't enough - unless you have a commercial license and can get the static binaries.
See: http://www.formortals.com/how-to-statically-link-qt-4/, http://www.formortals.com/build-qt-static-small-microsoft-intel-gcc-compiler/ and http://doc.qt.nokia.com/4.7-snapshot/deployment.html#static-vs-shared-libraries for more information.
Download already compiled libraries. If you are building against a platform, use cross-compiled libraries of that. You can link those libraries in Makefile statically [in #INCLUDE and LIBS variable in makefile]. The only drawback is your exe size will be increased.

Including external libraries to Qt

I am actually new at Qt and would be grateful if someone could explain how to deal with external C++ libraries in theses 3 cases and what is the easiest way to get a library working with Qt (if you could just point me out to some places where I can read about it):
- source .h and header .cpp files both available
- source .h and DLL
- source .h and .a files
I usually use the following procedure:
1- Cmake to generate make files
2- Building using Mingw:
Cd c:/test
qmake test.pro
mingw32-make
3- Including project to Qt:
INCLUDEPATH += C:/test/build/include
LIBS += C:\test\build\x64\mingw\lib\file.dll.a \ ...
I usually use Cmake first then qmake to build, but sometimes one is not working or often Qt option is not available in Cmake. I always read carefully the instructions. In general, how an experience programmer would make decisions on how to include a library?
You do not need cmake and qmake together -- One is enough. I mainly work with qmake when i'm in Qt Creator since it is well integrated with the IDE. Generally what you are doing is correct. You include headers under HEADERS +=, sources under SOURCES +=, libraries under LIBS += and the path to the include files under INCLUDEPATH +=.
Instead of manually adding the external library to the .pro file u can do one thing.
Right click on your main project, then select "add library" option then it will ask for
1. External library
2. Internal Library
3. System Library
then select External library , and rest all thing is done by the Qt Creator i.e it will automatically add the path to the .pro file and link the library to your project.