[PyKDE] Static compilation of PyQt

Phil Thompson phil at riverbankcomputing.co.uk
Fri Mar 3 09:59:27 GMT 2006


On Friday 03 March 2006 9:39 am, Gerard Vermeulen wrote:
> 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.

I think you would be able to use it, just that there would be some bloat as 
you lost the benefits of sharing the Qt DLLs.

I'm thinking of this as a packaging convenience for the majority of users for 
which standard Qt is all they need. It's a compromise between convenience and 
flexibility - there is nothing stopping somebody building things to meet 
their own specific requirements. There are similar issues in deciding, for 
example, which SQL drivers you include.

Phil




More information about the PyQt mailing list