Qt Application resources are missing in static build - windows

I trying to build Qt application under windows statically but after static build application resources are missing (I use custom icons).
I compiled Qt statically using the following commands:
configure -opensource -confirm-license -static -platform win32-g++ -opengl desktop -prefix "C:\Qt\5.13.0\mingw73_64-static" -skip webengine -nomake examples
mingw32-make
mingw32-make install
Using the dynamic version of Qt, everything works, the icons are missing only when I use static version. Icons in .svg format.
Also I tried to Q_INIT_RESOURCE but have the same result :(

Related

How to build Qt5 as static libraries under Windows

To distribute a Qt appication to Windows users as a simple .exe file, one would need to link statically with a static version of Qt libraries. Assume we distribute our license under an open license so that static linking of Qt is allowed. So we just need static library binaries of Qt5Core, Qt5Gui, Qt5Widgets. How to get them?
The binary distribution of Qt5 comes with dynamic libraries only. It contains some .lib files as well - but beware, these are not the static libraries, but some auxiliary files. They can be distinguished from true static libraries by their size: true static libraries are much bigger (many MB in the case of Qt5 components). So we need to statically compile Qt5 ourselves. This turns out to be surprisingly difficult.
The official instructions (http://doc.qt.io/qt-5/windows-building.html) are almost useless: Way too short, they do not even convey an idea of the difficulty of the task. A precise, up-to-date, step-by-step guide how to compile Qt5 into static libraries is currently missing. We should have it here.
The short answer: Don't waste your time on this. Link dynamically, and let an installer distribute your application. This is the only mode that is seriously supported by Qt5 and by CMake. Working without their support and against their advise is close to hopeless. Setting up an installer is far easier (though no fun either - we currenly use black magic from https://hk.saowen.com/a/d1cf90fcfea6d511629fd5a6c8113808721a7f19656677e8a5fab370a8d35cd4).
The long (yet incomplete) answer, in case you want to outsmart me:
The following steps brought me deceptively close to a solution. I succeeded in building static libraries, but I failed to link my application: Upon getting hundreds of LNK2001 and LNK2019 errors caused by cryptic unresolved external symbols, I had to give up.
So here comes a step-by-step description of what worked for me in October 2018 on a Windows10 virtual desktop. For each installation step, a check is indicated. If a check fails then fix the problem before proceeding further.
To start, install some tools that are needed later on:
Perl, needed for zlib and openssl configuration:
Skip if "perl -v" works.
Get installer from https://www.activestate.com/activeperl
Run installer -> will install to C:\Perl64.
Check: Restart terminal and try "perl -v".
An editor that can handle Unix end-of-line. Notepad won't do. Install vim, emacs, or whatsoever.
chocolatey package manager, needed to install flex and bison:
Run admin shell (Circle Menu > search for "Command" > right-click on "Command Prompt" > run as Admin)
Copy download command from https://chocolatey.org/install#install-with-cmdexe
Paste command to admin shell, and watch installation
Check: in terminal, try command "choco"
flex and bison, needed by qtbase compilation:
It's not obvious to get the right version of flex. From gnuwin32.sourceforge.net I got an outdated flex that missed a command-line argument required during Qt compilation. Compiling flex from source introduces a tail of further dependences. The simplest solution I found uses the Chocolatey package manager.
In admin shell, run: "choco install winflexbison3". This creates a directory X that contains the binaries win_flex.exe and win_bison.exe and a supporting "data" folder. Find out the location of X. In my case, X=C:\ProgramData\chocolatey\lib\winflexbison3\tools
Check: cd X, and run "win_flex --version", "win_bison --version".
During Qt compilation, these tools will be needed under their standard names "flex" and "bison". Therefore we need symbolic links flex->win_flex, bison->win_bison.
mlink X\flex.exe X\win_flex.exe
mlink X\bison.exe X\win_bison.exe
note: mklink needs absolute paths to work reliably
note: the symlink must not go to another directory lest bison won't find the "data" folder
Add X to the %PATH%
Check: in any shell, try "flex --version" and "bison --version"
So far for the tools. Now we need two libraries that must be statically linked to Qt (magic learned from https://stackoverflow.com/a/41815812/1017348):
Build static zlib:
Download https://zlib.net/zlib1211.zip
Unpack to C:\Development\zlib-1.2.11
Edit the file win32\Makefile.msc with an editor that can handle Unix EOLs:
Find the line starting with CFLAGS
Replace -MD with -GL -MT -Zc:wchar_t-
Find the line starting with LDFLAGS
Replace -debug with -opt:icf -dynamicbase -nxcompat -ltcg /nodefaultlib:msvcrt
Build zlib using the following command (should take less than a minute):
nmake -f win32/Makefile.msc AS=ml64 LOC="-DASMV -DASMINF -DNDEBUG -I." OBJA="inffasx64.obj gvmat64.obj inffas8664.obj"
Check: as a result, the source directory must contain zlib.lib (856kB), inter alia.
Build static openssl library:
Download https://www.openssl.org/source/openssl-1.1.1.tar.gz
Unpack to C:\Development\openssl-1.1.1
Copy files from zlib: cd zlib-1.2.11; xcopy zconf.h ..\openssl-1.1.1\ ; same for zlib.h zlib.lib zlib.pdb
cd ..\openssl-1.1.1
perl Configure VC-WIN64A no-asm no-shared zlib no-zlib-dynamic threads --prefix=C:\opt\local_x64
note: I added "no-asm" to avoid installation of NASM (Netwide Assembler)
note: I changed prefix, since only admins can install to C:\Windows
Edits the file ''makefile'':
Find the line that starts with: CFLAG
Append: /Zc:wchar_t- /GL /Zi
Find the line that starts with: LDFLAGS
Replace /debug with /incremental:no /opt:icf /dynamicbase /nxcompat /ltcg /nodefaultlib:msvcrt
Find the line that starts with: CNF_EX_LIBS
Replace ZLIB1 with zlib.lib
Build: "nmake"
Check: directory must contain openssl.lib (size?)
Now we are ready to build qtbase from source, using the command-line version of the Visual Studio C++ compiler:
Download (update location for latest Qt): https://download.qt.io/archive/qt/5.11/5.11.2/submodules/qtbase-everywhere-src-5.11.2.zip
Unpacking takes ca 20'
Move the source directory to the Local Disk (C:\Development)
To work with Visual Studio, use a specially configured terminal. Use Taskbar>Circle>Search to launch "x64 Native Tools Command Prompt for VS 2017"
cd qtbase...
Check: configure --help
configure -platform win32-msvc2017 -opensource -confirm-license -release -static -openssl-linked no-dbus -no-libpng -no-libjpeg -nomake examples -nomake tests -prefix C:\opt\local_x64 -I C:\Development\openssl-1.1.1\include -L C:\Development\openssl-1.1.1 -D OPENSSL_LIBS=C:\Development\openssl-1.1.1\libssl.lib
while debugging "configure", it may be necessary to delete config.cache.
option -I does not work with relative paths
the label "win32" may look wrong if we want to use Qt in a 64bit application, but we are advised not to worry: building Qt under Windows: really with "-platform win32-msvc2017"?
I don't know how to get rid of Sql: https://bugreports.qt.io/browse/QTBUG-71253
libpng and libjpeg are needed by optional code. They are provided in src/3rdparty, which tends to provoke clashes with system provided library versions. Therefore, we build without PNG and JPG support.
nmake
Check: static libraries (big .lib and small .prl) land in directory lib/
54.7 MB Qt5Core.lib
23.4 MB Qt5Widgets.lib
18.2 MB Qt5Gui.lib
07.4 MB Qt5Network.lib
...
That's it, we have static Qt libraries. Only, as said above, this did not help me when I tried to link my application with these libraries.

Compile QT and append a suffix to the generated DLLs name

Due to this error, I need to compile QT and generate the whole set of libs and DLLs with a custom suffix. Something like Qt5Core_MySuffix.dll, Qt5Gui_MySuffix.dll, Qt5Core_MySuffix.lib, and so on...
How can I do that? I am using this and this tutorials to perform the compilation.
Do I need to edit the configure.bat file?
Environment:
Windows7
MSVC2015
You can do this on configuration step. Where is an option qtlibinfix:
-qtlibinfix <infix> Renames all Qt* libs to Qt*<infix>.
Just add it to the configure command from you link:
configure -static -qtlibinfix MyInFix -debug-and-release -prefix “C:\Qt\Static\5.7.0” -platform win32-msvc2015 -qt-zlib -qt-pcre -qt-libpng -qt-libjpeg -qt-freetype -opengl desktop -qt-sql-sqlite -qt-sql-odbc -no-openssl -opensource -confirm-license -make libs -nomake tools -nomake examples -nomake tests
EDIT: I'm not sure if the BUG with not adding InFix to the Qt plugins is fixed. If not, you can easily fix it yourself. Take a look here

Including GTK# Dlls with Statically Linked (mkbundle)Mono Exe on Mac

I have an application coded in c# using the Mono Framework and GTK# for UI.Im trying to create a static bundle for MacOSX (including gtk# and mono runtime)
I just bundled Mono with my exe file using
mkbundle --static hello.exe -o --deps hello2.exe
I got the exe file but when i drag it and put it on the terminal i get System.DllNotFound Exception:glibsharpglue-2
I understand that i need to include the gtk# libraries.But i dont know how to do that with a statically linked mono runtime.Is there an option to do that using mkbundle.All i need to get is a final standalone package ready to run on Mac.
Please help me out.
UPDATE:
The shell script I'm currently using with Platypus to make the .app package
export DYLD_FALLBACK_LIBRARY_PATH="/Library/Frameworks/Mono.framework/Versions/Current/lib:$DYLD_FALLBACK_LIBRARY_PATH:/usr/lib"
exec /Library/Frameworks/Mono.framework/Versions/Current/bin/mono myapp.exe
Im currently using the option provided in platypus to include myapp.exe file.How can i include the dlls required for GTK? Please help me out.
The error is from not finding the GTK shared object libraries (SO/dylib).
Using mkbundle:
If using 32-bit Mono you will need to assign the arch type for AS and CC. By default, clang will compile and link x86_64 which may not match your installed Mono's arch type.
export AS="as -arch i386"
export CC="cc -arch i386 -framework CoreFoundation -lobjc -liconv"
mkbundle gtkdesigner.exe --deps -o gtkdemo
The resulting executable will still require Mono (and any dependant shared objects/dylibs) to be installed.
Or adding --static to statically link to mono libs and thus invoking the LGPL of Mono (you will need to distribute your original CIL images so the user can upgrade the version of Mono that is running your app, unless you have a license from Xamarin)
mkbundle --static gtkdesigner.exe --deps -o gtkdemo
The resulting executable will not require Mono to be installed, but any dependant shared objects/dylibs will still be required.
GTK/GTK# based applications:
A GTK# based application will still require the GTK shared objects/dylibs to be installed and accessible by the resulting executable (i.e. gtkdemo in this case):
Thus if you try to run ./gtkdemo it will need to find shared libraries such as libc.dylib, libgtksharpglue-2.so, etc, etc... otherwise the error you are getting will be shown.
Set the dylib library path to your GTK libraries, not the C# CIL binding library (GTK#), but the native shared object libraries. Since you have Mono installed on OS-X, it also installs its own version of GTK that can be found at /Library/Frameworks/Mono.framework/Versions/Current/lib. If you are installing your own version GTK to a different location just change the path to that location. You also will be to include the location of the OS's std C library.
export DYLD_FALLBACK_LIBRARY_PATH="/Library/Frameworks/Mono.framework/Versions/Current/lib:/usr/lib"
./gtkdemo
Note: You can package this gtkdemo application into a normal OS-X app by using a packager tool such as http://sveinbjorn.org/platypus. Package all the GTK libraries and any other required so/dylibs into the app and provide a shell script that assigns the DYLIB path in order to find those app based GTK libs. Then you can distribute the self-contained app and the end-user just double-clicks it to run you GTK-based app.
Since gkt# is an open-source library why not download the code?
You would need to install git and do:
git clone https://github.com/mono/gtk-sharp
Then, you can reference those donwloaded gtk-sharp projects directly in your solution.
Note: i believe you still need the native OSXs gtk libraries since gtk-sharp is a wrapper of those libs.

Issue in QT 4.8.6 with QPA configured on Mac OsX

I have a strange issue with the qt libraries built with QPA configured. Configure that I use is
./configure -release -opensource -confirm-license -shared -qpa
Once Qt libraries are done compiling,when u check the dependency on each libraries, its giving dependency on each libraries even though linking while building was successful. For example, libQtGui.dylib library shows a dependency on libQtCore.dylib. Similarly for other Qt libraries. Only library that doesnot give any dependency is QTCore dynamic library. Well this is really strange, considering I have built and installed in the same machine and when I try to build a GUI application it links fine but gives dependency issues when i launch it.
I dont have any other qt libraries installed and googled this issue without any help.

how to deploy qt based application with oracle plugin

just wrote application based QT with OCI plugin but i can't deploy it.
i did the following steps:
installed QT 4.7 SDK
Installed the OCI plugin:
set INCLUDE=%INCLUDE%;c:\oracle\oci\include
set LIB=%LIB%;c:\oracle\oci\lib\msvc
cd %QTDIR%\src\plugins\sqldrivers\oci
qmake -o Makefile oci.pro
nmake
i followed: "Building static Qt on Windows with MSVC"
edited the \mkspecs\win32-X\qmake.conf:
QMAKE_CFLAGS_RELEASE = -O2 -MT
CONFIG += qt warn_on release incremental flat link_prl precompile_header autogen_precompile_source copy_dir_files debug_and_release debug_and_release_target
then on the Qt dir:
configure -static -release
nmake sub-src
i'm not sure about the next steps but in my application dir i ran:
qmake -o Makefile myProgram.pro
nmake
i get .exe file in release but i get error that the OCI driver is not loaded...
please assist me ,
i had no errors in any step i made
Shouldn't you first compile your static version of Qt and then compile the OCI plugin? You could also do this in one step by setting the appropriate configure switch -qt-sql-oci and adding the required include and lib dirs.
Because, in your scenario, which qmake did you use to compile your OCI plugin? The static one you intend to use for your app isn't build yet. So it seems your OCI plugin was build with one Qt version, whereas your application uses another (static) Qt version. This mismatch is most probably the cause of your problem.
Also, when using static plugins, you have to use the Q_IMPORT_PLUGIN macro. See here for more details http://doc.qt.io/archives/qt-4.7/plugins-howto.html#static-plugins
As requested, here a step by step instruction how it should work:
Extract the qt sources for your static Qt version, lets say in C:\Qt\4.7.0-static
Change qmake.conf the way you already did.
In your visual studio command line, change directory to C:\Qt\4.7.0-static and do this:
configure -static -release -qt-sql-oci -I C:\oracle\oci\include -L c:\oracle\oci\lib\msvc
Do a nmake sub-src
Then, change the qt version you use for your app to the one just compiled and execute "Run qmake" and "Rebuild project" from the build menu in QtCreator (as you installed Qt SDK, I'm assuming you're using it)
It hopefully works now - using the -qt-sql-oci switch causes a static build of the oci driver.

Resources