[PyKDE] Static compilation of PyQt

Gerard Vermeulen gerard.vermeulen at grenoble.cnrs.fr
Fri Mar 3 09:39:19 GMT 2006

On Fri, 3 Mar 2006 08:57:50 +0000
Phil Thompson <phil at riverbankcomputing.co.uk> wrote:

> On Thursday 02 March 2006 11:31 am, Giovanni Bajo wrote:
> > Hello,
> >
> > For the past few months, I have been using a statically-compiled version of
> > PyQt. "Statically" here means that it's still an external module (.pyd) but
> > it does not depend on the external C++ Qt DLL: the module is totally
> > self-contained. This bring several advantages:
> >
> > - Size. A static version of PyQt (snapshots of December) with Qt 3.3.5, and
> > modules Core + OpenGL, is 1.1 Mb (compressed with UPX). When using Core +
> > OpenGL + Canvas + Table, size is 1.3 Mb. The size win is given by the
> > saving of almost 1,5 Mb of import and export sections (respectively in
> > qt.pyd and qt-mt335.dll), which are not necessary anymore. The sections are
> > *very* large because C++ name mangling is bloated as we all know.
> >
> > - Ease of mainteance. A single file is easier to update, copy around, and
> > whatnot. I have several versions of PyQt and Qt in my computer and I don't
> > have to wonder anymore which version of PyQt goes with which Qt DLL.
> >
> > - Minor startup speed benefit. A *cold* import of PyQt on my computer is
> > now roughly twice as faster than before (0.4 seconds instead of 0.9
> > seconds). "Cold" import means after flushing all disk caches. Notice that
> > this is the time which matters most for users as they tipically don't
> > execute GUI applications many times in a row and thus they do not benefit
> > from OS caching.
> >
> >
> > It also brings a couple of disadvantages:
> >
> > - Change of API. Since you need to have a single file qt.pyd with all the
> > modules in it, there are name changes in the application. For instance
> > QTable is imported from "qt" and not "qttable". This doesn't matter much if
> > you use the "from qt import *" syntax, but it still poses a compatibility
> > problem (existing code using "from qttable import *" won't work).
> >
> >
> > I would like to stress that the size improvement is a very good sell point
> > for PyQt4/Win. Currently, users shipping Python GUI applications under
> > Windows (with tools like PyInstaller and py2exe) always complain of the
> > fact that the final size of the application is too large (especially
> > compared with the small Python source code that produces it). wxWidgets is
> > a huge bloat of some 10Mb, for instance, but given that Qt3 wasn't free for
> > Windows there weren't many options for free development. With the advent of
> > Qt4 and PyQt4, I'm sure many will evaluate PyQt4, and will surely look at
> > the distribution size.
> >
> > Alas, I haven't looked into PyQt4 yet (and still won't for some months), so
> > I can't really contribute a patch for there. But I do have a script to
> > compile PyQt3 statically which I'm willing to contribute. I would like this
> > to become part of the official build system for PyQt. Notice that currently
> > compiling PyQt with a statically-compiled Qt leads to a crash if you use
> > more modules (as each pyd, eg. qttable.pyd, will contain a full copy of the
> > Qt C++ code). So this might simply be the default way of building PyQt when
> > a statically-compiled Qt is detected.
> >
> > BTW, for PyQt3, the steps are really easy:
> >
> > 1) Compile Qt statically (produce qt-mt.lib)
> > 2) Merge all the modules of PyQt you're interested in into qtmod.sip (you
> > *must* build only qt.pyd).
> > 3) Build qt.pyd only.
> >
> > I have a Python script which does the module merging.
> I think this is a good idea, but...
> 1. Changing the API isn't acceptable, "import qttable" must continue to work.
> 2. I don't want to do this for PyQt3 - unless doing it for PyQt4 makes it 
> trivial to do for PyQt3. The primary beneficiary will be Windows GPL users.
> You can solve 1. by flipping Gerard's idea around for Qt.py and generating a 
> qttable.py that contained...
> from qt import QTable, QTableItem, ...
> The problem with this is that this is probably better handled by SIP rather 
> than the build system. A SIP implementation would also go a long way to 
> solving 2. It would probably also generate a C module rather than a Python 
> one.
> SIP could be changed to support something like...
> %ConsolidatedModule qt
> %Include qtmod.sip
> %Include qttable.sip
> ...and PyQt's configure.py would have an extra flag to specify that the 
> consolidated version should be built. It's up to you whether the Qt you are 
> linking against is static or dynamic.

Support for static linking is a great idea, but I am a little bit worried that
it won't be possible to use PyQt addon packages (PyQwt for instance) with a
statically linked PyQt.


More information about the PyQt mailing list