📜 ⬆️ ⬇️

Static build dll-library with QtQuick modules

Good day, readers. In this article I will try to tell as much as possible about how I built a statically dll library with QtQuick modules. Climbing all the Internet, I could not find a solution to my problem, but it turned out to be under my nose.

I will begin from the very beginning, namely: from Qt weaning from libraries * .dll. Operated: Qt-windows-x86-MinGW-5.5.0-rc, snapshot 95 from 2015.06.17 . Work Environment: Windows 8.1

I know that such articles have already accumulated a decent handful, but what to do ... I had to rebuild different versions of Qt four times before the dll he collected started loading as it should. Immediately I will warn you that QtWebKit will be cut out in this build. If you already have a static Qt build, feel free to scroll through this manual to the most interesting .

So let's get started!
  1. Download the required set of software:

    It is possible that Python and Ruby are not needed at all, but since In all the manuals, both of them appear as "mandatory" and we absolutely do not need surprises, we will install them.
    ')
  2. Install / unpack to any directory. I had C: / Qt for Qt and its sources, and C: / dev for the rest of the software. When installing Qt, be sure to check the Qt -> Tools -> MinGW checkbox.

    Installation configuration


    Source Components should not be installed, we downloaded them separately in the archive (already, probably, unpacked?), And we will work with them.

    Tree
    • C: / dev / StrawberryPerl
    • C: / dev / Ruby22
    • C: / dev / Python34
    • C: /Qt/Qt5.5.0 - Qt version installed
    • C: /Qt/qt-everywhere-opensource-src-5.5.0-rc - unpacked source


  3. Edit qmake configuration:
    • open the qt-everywhere-opensource-src-5.5.0-rc / qtbase / mkspecs / win32-g ++ / qmake.conf file
    • find the string
      QMAKE_LFLAGS = 

      and replace it with:
       QMAKE_LFLAGS = -static -static-libgcc 
      ( 5.5.0-rc had line 70 )

  4. Mysterious bug c qmldebugger


    irrelevant in new versions, skip this step

     lib\libQt5Qml.a(qqmldebugserver.o):qqmldebugserver.cpp: undefined reference to `QTcpServerConnection::QTcpServerConnection()' 

    Fix
    Because of this bug, in fact, I had to collect two of the four versions of Qt, until I found a description of the problem on the Internet. Unfortunately, I did not understand what place this patch should have been patched (I will be glad if you tell me), so I acted extremely radically and ugly: treacherously cut out the problematic line from the source. I think to practice such acts is not worth it, but once you can =)
    Ps: I'm not quite sure that it was in the end that saved my time and nerves, because at the same time with this change, I added the -qml-debug parameter to the collector. If you want to risk and sacrifice your time, then do not change the source code, but configure the assembly with the -qml-debug parameter, perhaps the problem will become irrelevant.

    Go to the qt-everywhere-opensource-src-5.5.0-rc \ qtdeclarative \ src \ qml \ debugger directory , open the malicious qqmldebugserver.cpp file and comment on the objectionable line:
     #if defined(QT_STATIC) && ! defined(QT_NO_QML_DEBUGGER) // #include "../../plugins/qmltooling/qmldbg_tcp/qtcpserverconnection.h" <----   #endif 



  5. We start the MinGW terminal
    Start -> All Programs -> Qt 5.5.0 -> 5.5 -> MinGW

    and we feed him something like this code:
     #      ! set QTSRC=C:\Qt\qt-everywhere-opensource-src-5.5.0-rc set MINGWPATH=C:\Qt\Qt5.5.0\Tools\mingw492_32\bin set QTPREFIX=C:\Qt\5.5.0_Static set PYPATH=C:\dev\Python34 set PERLPATH=C:\dev\Strawberry\perl\bin set RUBYPATH=C:\dev\Ruby22\bin 

    Where:
    QTSRC - unpacked Qt sources
    MINGWPATH - the path to the MinGW installed with Qt
    QTPREFIX - the place where the Qt static assembly will be installed
    PYPATH - the path to the installed Python
    PERLPATH - Perla bin folder path
    RUBYPATH - path to the Ruby bin folder

    Further:
     set QTDIR=%QTSRC%\qtbase set PATH=%PATH%;%MINGWPATH%;%PYPATH%;%PERLPATH%;%RUBYPATH%;%QTDIR%/bin cd %QTSRC% mkdir nomake move qtwebkit nomake move qtwebkit-examples nomake 

    this is where binary search paths are set, and the last three lines cut WebKit from the assembly (the -no-webkit flag has disappeared somewhere from the configuration file). I want to note that to connect plug-ins without a tambourine, it will not be enough to assemble only one qtbase, so we go to the folder with the source % QTSRC% and collect everything that is there.

  6. Run the configurator:
     configure -static -release -opensource -confirm-license -opengl desktop -no-angle -qml-debug -c++11 -platform win32-g++ -qt-zlib -qt-pcre -qt-libpng -qt-libjpeg -qt-freetype -no-openssl -make libs -make tools -nomake examples -nomake tests -prefix %QTPREFIX% 

    shotaku?
    • -static - no comments;
    • -release - specify that we will only collect the Release version (if you need debug, then change to -debug );
    • -opensource -confirm-license - agree with the license;
    • -opengl desktop build for "desktop";
    • -no-angle - “will get rid of libEGL, libGLES”, thanks Taraflex : Toster ;
    • -qml-debug - we allow debag Kumla. The same parameter that possibly cures bazhig with qmldebugger (point 4);
    • -c ++ 11 - ... - we allow to use;
    • -platform win32-g ++ - target platform ( yes, only 32 bits );
    • -qt-zlib -qt-pcre -qt-libpng -qt-libjpeg -qt-freetype - buns;
    • -no-openssl - disable ssl (I did not need it);
    • -make libs - this is useful for us to build dll-library;
    • -make tools are tools of dubious necessity, which I decided to keep. It seems to be an assistant, designer and linguist. If you do not need it, replace it with -nomake tools ;
    • -nomake examples -nomake tests - examples and tests. They gather about-oh-oh-oh-ry long, so it is better not to include;
    • -prefix% QTPREFIX% - specify where the future build will be installed. ( % QTPREFIX% was specified at the very beginning of the fifth paragraph);

    • if you need any other modules, for example, sqlite , then read the README or use the configure -help command to find out which parameter you need to add to the configurator.


  7. Run the build:
     mingw32-make -k 

    ps if you have a multi-core processor, you should indicate to the builder their number with the -j parameter [ number of cores - 1 ] . Those. for my 4-core processor, I launched the assembler like this:
     mingw32-make -k -j3 

    the parameter - k seems to order the collector to stop, if suddenly "something went wrong." This unpleasant situation did not touch me, so I will not argue.

  8. Run the installation:
     mingw32-make install 

    after that, we should have a % QTPREFIX% directory with the collected libraries.

  9. Add a kit to build statics:
    1. Run QtCreator , which was installed with Qt5.5.0-rc
    2. go to Tools> Options ...> Build and Run> Qt Versions , add a new qmake from the % QTPREFIX% \ 5.5.0 \ bin directory , call it something like this: " Qt% {Qt: Version} (% {Qt: Version} _Static) "and click the button" Apply "
      Qt Versions


    3. go to the " Kits " tab, click " Add ", call it something like this: " Qt5.5.0-Static ", compiler: MinGW , profile: " Qt% {Qt: Version} (% {Qt: Version} _Static) " , click the " OK " button
      Kits
      image



That's all. And now, finally, the most interesting .


Static build dll-library with QtQuick modules


Create a new project in QtCreator:


The whole point of the fact that dll-libraries were not going to statically ( or rather they were going to be, but were not working ) was that the template ( TEMPLATE ) used to build the DLL ( lib ) does not include linking of plug-ins. Therefore, all of them need to register manually in the header and .pro-file .
Get a list of all the necessary plug-ins was not difficult:

In the same directory, open the Makefile.Release file and retrieve the necessary information from there, namely: a list of libraries that should be connected to the project:
 LIBS = -lmingw32 -LC:/Qt/5.5.0_Static/lib -lqtmain -LC:/Qt/5.5.0_Static/qml/QtQuick.2 -lqtquick2plugin -LC:/Qt/5.5.0_Static/qml/QtQuick/Window.2 -lwindowplugin -LC:/Qt/5.5.0_Static/plugins/platforms -lqwindows -lwinspool -lshlwapi -lQt5PlatformSupport -lqtfreetype -LC:/Qt/5.5.0_Static/plugins/imageformats -lqdds -lqicns -lqico -lqjp2 -lqmng -lqtga -lqtiff -lqwbmp -lqwebp -LC:/Qt/5.5.0_Static/plugins/qmltooling -lqmldbg_qtquick2 -lQt5Quick -lQt5Gui -lcomdlg32 -loleaut32 -limm32 -lwinmm -lglu32 -lopengl32 -lgdi32 -lqtharfbuzzng -lqmldbg_tcp -lQt5Qml -LC:/Qt/5.5.0_Static/plugins/bearer -lqgenericbearer -lqnativewifibearer -lQt5Network -ldnsapi -lQt5Core -lole32 -luuid -lws2_32 -ladvapi32 -lshell32 -luser32 -lkernel32 -lmpr -lqtpcre 

All this will need to be added to the .pro file of your future project (the list may differ, depending on your version and which modules you turned on / off when building Qt, so better copy this list from your PC ). It does not hurt to add the path to the Qt static assembly header files:
 INCLUDEPATH += C:/Qt/Qt5.5.0_Static/include 



After you make these changes to the project, you can build the QtQuick mini-framework as a single DLL. What do you do with it, I do not know, but I hope someone will find this information useful :)

.pro-file of my project 'MyDll'
 QT += core widgets qml quick CONFIG += dll TEMPLATE = lib TARGET = mydll DEFINES += MYDLL_LIBRARY SOURCES += mydll.cpp HEADERS += mydll.h \ objectfactory.h INCLUDEPATH += C:/Qt/Qt5.5.0_Static/include LIBS += -lmingw32\ -LC:/Qt/5.5.0_Static/lib -lqtmain\ -LC:/Qt/5.5.0_Static/qml/QtQuick.2 -lqtquick2plugin\ -LC:/Qt/5.5.0_Static/qml/QtQuick/Window.2 -lwindowplugin\ -LC:/Qt/5.5.0_Static/plugins/platforms -lqwindows -lwinspool -lshlwapi -lQt5PlatformSupport -lqtfreetype\ -LC:/Qt/5.5.0_Static/plugins/imageformats -lqdds -lqicns -lqico -lqjp2 -lqmng -lqtga -lqtiff -lqwbmp -lqwebp\ -LC:/Qt/5.5.0_Static/plugins/qmltooling -lqmldbg_qtquick2 -lQt5Quick -lQt5Gui -lcomdlg32 -loleaut32 -limm32 -lwinmm -lglu32 -lopengl32 -lgdi32 -lqtharfbuzzng -lqmldbg_tcp -lQt5Qml\ -LC:/Qt/5.5.0_Static/plugins/bearer -lqgenericbearer -lqnativewifibearer -lQt5Network -ldnsapi -lQt5Core -lole32 -luuid -lws2_32 -ladvapi32 -lshell32 -luser32 -lkernel32 -lmpr -lqtpcre 



mydll.h
 #ifndef MYDLL_H #define MYDLL_H #include <QtPlugin> Q_IMPORT_PLUGIN(QWindowsIntegrationPlugin) Q_IMPORT_PLUGIN(QDDSPlugin) Q_IMPORT_PLUGIN(QICNSPlugin) Q_IMPORT_PLUGIN(QICOPlugin) Q_IMPORT_PLUGIN(QJp2Plugin) Q_IMPORT_PLUGIN(QMngPlugin) Q_IMPORT_PLUGIN(QTgaPlugin) Q_IMPORT_PLUGIN(QTiffPlugin) Q_IMPORT_PLUGIN(QWbmpPlugin) Q_IMPORT_PLUGIN(QWebpPlugin) Q_IMPORT_PLUGIN(QtQuick2Plugin) Q_IMPORT_PLUGIN(QTcpServerConnection) Q_IMPORT_PLUGIN(QGenericEnginePlugin) Q_IMPORT_PLUGIN(QNativeWifiEnginePlugin) Q_IMPORT_PLUGIN(QtQuick2WindowPlugin) #include <QGuiApplication> #include <QQuickView> class MyDll { ... }; #endif 

Source: https://habr.com/ru/post/261479/


All Articles