Very large .app bundle created when deploying Qt app on OS X - qt

I have been using Qt for a while on Linux and Windows. However, yesterday I picked up a new MacBook Pro so naturally I've been playing around to see if I could build my Qt apps on Mac.
I got pretty much everything working, however there is one problem : the file size of the resulting app bundle.
I am building my application like this:
qmake -spec macx-g++
make
macdeployqt my.app -no-plugins -dmg
The bundle and everything seem to work fine, but, the generated .app is 31.1 MB large and the .dmg is 13.6 MB!
Is this normal? Can I reduce this horrible size (on Windows, my installer for the same app with all the libraries is ~4 MB)?

If you are using the pre-built Qt libraries then the chances are that they are universal binaries with multiple architectures. For example, do $ file my.app/Resources/Frameworks/QtCore.framework/Versions/4/QtCore and you will see multiple architectures.
You can build your own Qt libraries with only the architectures that you want to support. You may wish to not support PPC because that is ancient; or if you are using a current Qt then you can make the decision of 32 bit vs 64 bit, but that's another question.

The problem is the size of the Qt dynamic libraries, as they must be part of your bundle.
These sizes can usually be reduced.
See the solution of How do I make apps smaller with qmake and macdeployqt on how to do this.
An excellent workaround would be a static build of Qt and linking your application against the static build. This usually is a very good idea as two applications installing Qt dynamically usually crash on Mac OS.
Your application will have with static build (from my exp.) approx. 10-20MB of size. Combined with the steps above, some more reduction might be possible.

Related

Sharing Qt libraries among Qt applications

Our company ships 2 Qt applications, for now, using Qt5.6 but in some time there will be more (using newer Qt versions). So the problem is, how to make them work all together with different Qt versions? We won't be able to rebuild all Qt apps shipped before, especially if there will be plenty of them. I don't think it's a good idea to place all necessary Qt libraries with each app because the repository size will grow fast. And I think it's just not wise to have many Qt dlls of the same version at one place. As long as I know, .NET solve such problem of different versions with assemblies installer, but I don't think it can help me with Qt. So any ideas of how can I solve it would be highly appreciated. Thanks
UPD: The system is Windows
Actually an answer is quite straightforward, you can ship one Qt version (binaries) as long as they are binary compatible. With each release Qt announce binary compatibility or non-compatibility, so if for whatever reasons you need to switch to newer version and ship new applications with newer not compatible version you might want to ship a new Qt DLL chain.. This can be achived differently (depends on how you layout you install), for example you can have a common lib dir with sub directories based on Qt version which you will extend. (of course you will need appropriate PATHS set then running different applications) :
app\
app\app01
app\app02
...
lib\
lib\Qt5.6.1
lib\Qt5.7.0
etc, then you will have (for example) to wrap your exe files to .bat like:
run.bat
SET PATH=....\lib\Qt5.6.1\
app01.exe
etc..
it's all depends on your install layout and goals

Memory Usage of Qt Application on mobile device

I was testing with simple qt quick application on android & ios device. For android,memory usage is 31 MB where as for IOS it jumps to 41 MB.
Installing through ministro requires active internet connection.Upon deploying,I see a lot of Qt libraries getting added,can't we remove it?
Installed Qt libraries should only the ones used by your project. See your .pro file and remove unused Qt dependencies (QT flag).
For the size difference, I'm pretty sure deploying on windows will require a different memory usage. It's hard to say why one uses more memory. Every platform and compiler have there specificities and will end up with different binary sizes. There could be some compiler options to optimize by size, but speed peformance will be shown down.

QT5.0.2 project needs more DLLs than QT4.8

Recently we moved to QT 5.0.2 from QT4.8. Our project now needs more DLL files than the earlier. It requires qml, opengl, printer modules. However we did not use any of these modules in our application. The size of exe file increased due to additional DLLs.
QT-= qml opengl -> did not exclude this module from our application.
Are these additional DLLs are compulsory for Qt 5.0.2 ? Is there any way to come out from this? We need to exclude these dlls to reduce exe size.
Some of the modules you use may be dependent on those you don't, which means your project depends on them indirectly. For example, by default, some modules (QtWebKit, QtMultimedia) utilize ANGLE which uses OpenGL. You can try to trace those dependencies by using a program named Dependency Walker (available here). The Qt GUI has changed a lot since 4.8, and there are now separate modules for printing and other functions (see here).
Sources:
Qt 5 on Windows ANGLE and OpenGL
Qt 5 Deployment on Windows
By the way, someone has (had) a similar problem: http://www.qtcentre.org/archive/index.php/t-52102.html. (Unfortunately, there is no solution in that link.)
It turned out that this is actually a bug in Qt.

Deploying QT app on OS X and linux

Whats the best way to deploy a QT app? I've read the documentation hosted at trolltech but is it better to link with a static library or the dynamic libraries and have the user install the framework? I don't really want anyone using my app to have to download a 160mb framework just to run a simple gui frontend.
On OS X it's a good way to do a dynamic build and post-process the resulting ".app" with the macdeployqt tool which comes with Qt starting with 4.5.
This will copy the Qt frameworks used by your application into the application bundle, which results in a larger package than building a static version of your application.
Here is what you can do to make sure you get the smallest file size possibly in a dynamic build:
First off, make sure you only include the stuff you need (in the project.pro file's QT += core gui network xml lines).
Open the application bundle and remove any unneeded "Qt Plugins" from the bundle. macdeployqt automatically compies all the Qt plugins in there, which can be kind of bulky.
Make sure you are building your application in release mode. Otherwise your application might be linked against the debug libraries of the Qt4 framework, and they are really big (for instance, well over 90 MB for the debug library vs. 16 MB of a release variant without debugging symbols). This might be what happened in your case.
If you have a large application binary, you can use UPX to compress your executable file by 40-50%.
Other than that, you should use compressed disk images to deploy your application.
One of my projects uses QtGui, QtNetwork, QtCore and QtXml and the resulting bundle is about 16 MB in size.
Hope that helps.
Unfortunately you will have to include the Qt libraries you need into your own bundle, as you cannot expect your users to have Qt installed on Mac (whereas on Linux packaging systems allow you to require at least a given version of Qt.
There is a nice tool to help you with that, which is called macdeployqt. You just need to invoke it on your bundle application and it will pack the required libraries, changing the linkage of your binary to refer to them. Without it, making bundles for Mac is a real pain (it still is, but considerably less though).
http://doc.trolltech.com/4.6/deployment-mac.html#the-mac-deployment-tool
Afterwards, you can make a .dmg image as you would do with any other app. There is an option in macdeployqt that builds a basic one.
On Linux, it's better to rely on the OS's copy of Qt, as it's almost certainly installed - for OS X, almost all apps use a statically compiled library.

How to build QTcore4.dll without dependency to MSVCx80.dll?

I have a windows screensaver that I want to recompile using the QT libraries, so that I can make available for more platforms.
I am facing problems with the deployment on Vista and XP.
I compile my screensaver statically with MT, and run the dependency checker.
The results are:
MyScreensaver.SCR needs several DLLS, QTCORE4.DLL but no MSVCx80.DLLs.
So far this is fine.
My problem is that QTCORE4.DLL in its turn, does need MSVCP80.DLL and MSVCR80.DLL
As a result my application does not run on Vista systems.
Can I build QTCORE4.DLL to be statically linked the the microsoft libraries (maybe Libcmt.lib ?) so that I do not have any dependencies in the MS CRT DLLs?
Limitations:
I do not want to have the users install the MS VC redistributables. The screensaver is only 1 MB, and it is ridiculus to ask the user to do so many changes in his computer just for a screensaver.
I do not want to use the trick to put the MS CRT dlls in the same application path with the screensaver because screensavers are installed in system32, and I want to install the minimum possible files there.
Finally, I do prefer to produce a monolithic program, rather that a bunch of DLLs
I tried a full static compilation and link of QT, but this is not allowed (if I understood correctly, by the LGPL) and also it is not recommended according to this: http://www.qtsoftware.com/developer/faqs/why-does-a-statically-built-qt-use-the-dynamic-visual-studio-runtime-libraries-do-i-need-to-deploy-those-with-my-application
After trying for solutions in various directions, it seems the most feasible one is to use the QTCore4.dll and QTGui4.dll, but having them linked statically to MSVCRT. In this way, neither my program, nor the QT DLLs will have dependencies on MSVCRT dlls.
Is there a solution to this?
( I am new to QT programming )
Thank you,
Michael
I think they are concerted that parts of your application will be compiled with /MD(d) and parts with /MT(d), but if you control everything (including 3rd party libraries) then its pretty safe to use /MT(d).
You have two options:
Those dependencies are part of Microsoft Visual C++ Runtime Library, you can deploy that library in your installshield and user silently installs it, MSVCRT library not included in Windows by default, you must deploy runtime library in your installshield and copy Qt*.dll DLLs in your application directory.
Use Static Linking of Runtime and Qt main dependencies, with this option you have one executable file, but to static compile of Qt you must have Qt commercial License for commercial use.

Resources