Question

I recently followed a discussion on the Qt4-interest mailing list about whether it is legal or not to build a commercial/proprietary application and statically link Qt4 into it. While there are some non-proven ways of doing so (by providing object files and a Makefile, etc. to the customer), it doesn't sound like such a good idea afterall.

One of my projects is using the LGPL-licensed Qt4 libraries and I ship them as separate DLLs/Dylibs/so's to my customer, using a simple installer on all platforms. While this works pretty good so far, I'd like to optimize a) the size of the installer by reducing the Qt library size by just including what I need, b) increase the startup/loading speed of my application.

I'm familiar with compiling Qt myself, but Qt got a lot of flags and switches.

Right now I'm building with the following flags:

./configure \
  -fast \
  -opensource \
  -qt-sql-sqlite \
  -nomake demos examples \
  -silent \
  -no-qt3support \
  -no-gif \
  -plugin-sql-mysql \
  -release \
  -no-xmlpatterns \
  -no-multimedia

I'm not entirely sure which effect/impact the following flags have:

  • -no-stl
  • -no-javascript-jit
  • -no-nis
  • -separate-debug-info
  • -no-openvg
  • -no-mitshm

Is there anything else I can do, for instance, by providing optimization switches for the compiler, or "stripping" unused functions out of the built Qt library to make it smaller (which would be easy with static builds). I don't have much experience with that.

Oh, just as a side-note, my compiled application size is about 600 kb (non-stripped) when linking against Qt dynamically. I experimented with it and found it to be around 4 MB in size when I link statically; but that way I wouldn't have to include 40 MB of Qt libraries anymore.

So, to put everything above into a question/request:

If you are more advanced than me on this topic, how do you optimize/deploy your own applications and make sure they start fast and only contain what is needed?

Was it helpful?

Solution

There are few things that I can think of:

  • use a compiler/linker combination that does good size optimizations. MSVC is much better at this than MinGW for instance. All the Qt release DLLs built with MSVC total at ~21 MB. Built with MinGW they total at ~41 MB. By the way, do you really need to ship all the DLLs?
  • use the -ltcg (Link-time code generation) flag to optimize across object files.
  • use preprocessor flags to exclude parts of the Qt functionality. e.g: QT_NO_STL = -no-stl.
  • try the mmx/3d now/sse2 flags
  • remove some of the styles (-no-style-)

OTHER TIPS

When you have skipped all modules and such that you feel you don't need, then you can continue using the qconfig tool (kind of hidden in the $QTDIR/tools/ tree) and remove individual classes. Just beware of dependencies - you might have to iterate a few times to get Qt to build (for instance, QSpinBox depends on QValidator being present).

When building Qt, especially multiple times, the -nomake flag is a great timesaver. Try -nomake examples -nomake demos.

Another optimization for general speed lies in using compiler optimisations when compiling Qt, but you have to edit some files. When you get Qt from Git, you end up with a qtbase/ dir. First you execute the configure script, which builds qmake

Note: you can modify Makefile.win32 or Makefile.unix and add lines like :

QMAKE_CXXFLAGS_RELEASE = -CompilerDependentOptimizerSwitches 

if you want qmake to be optimized, but I don't think it is really necessary, considering that the running time of qmake might be 0.0000001% of the whole compile time for a medium-sized app.

But the real optimisation comes when editing the mkspecs that are used to build Qt.

For instance, under windows with VS2012, you would likely modify qtbase/mkspecs/win32-msvc2012/qmake.conf.

Ex. : on default Qt5.1, the msvc2012 mkspec reads :

QMAKE_CFLAGS_RELEASE    = -O2 -MD
QMAKE_CXXFLAGS_RELEASE  = $$QMAKE_CFLAGS_RELEASE

Since you want to optimize for size, you could replace it with :

QMAKE_CFLAGS_RELEASE    = -O1 -MD

(According to http://msdn.microsoft.com/en-us/library/8f8h5cxt.aspx )

Sometimes it includes more high-level mkspecs found in qtbase/mkspecs/common/ dir.

I successfully compiled Qt5.1 on Debian/g++4.8.1 with -O3 -march=native (the default is -O2) if it serves anyone.

After doing this, just run make on the Qt git root, and go have a beer with your team because even on a good computer it will take ages (approx. 2h on an i7, without building demos / examples, but with webkit).

sed -i 's@QMAKE_CXXFLAGS_THREAD  += $$QMAKE_CFLAGS_THREAD@QMAKE_CXXFLAGS_THREAD  += $$QMAKE_CFLAGS_THREAD -march=native@g'  qtbase/mkspecs/common/linux.conf

Will optimize Qt5.8 on Linux

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top