This tells how to build PyQt5 for Python 2.7 on a newly installed Ubuntu 13.10. The problem is that Ubuntu 13.10 defaults the command ‘python’ to version 2.7.5, and Ubuntu repositories don’t provide a compatible PyQt5 package. (The package ‘python3-pyqt5’ installs with Python 3 packages, and won’t be found if you run ‘python’ instead of ‘python3’.)
The audience is developers who for any reason want to stick with Python 2.7. Many will just use ‘python3’ and the packages provided by Ubuntu.
- One reason you might want Python2.7 is that you are using PyQt because it is cross-platform, and you are waiting until Python 3 is blessed on all your platforms.
/usr/local/include/python2.7
- Another reason is you are using pyinstaller, which doesn’t support Python3 yet
This is tedious, and you wait about an hour.
In my opinion, it illustrates needless complexity surrounding:
- the transition to Python 3
- different Linux distribution’s ‘standard’ file hierarchy
- the overly flexible Linux packaging philosophy: ‘don’t distribute everything, and track dependencies.’
Finally, you might need this recipe on Ubuntu 14.04 also.
The reason for a build machine
A build machine has a well-documented configuration. On a ‘development’ machine (hacked by a programmer), you might not be absolutely sure what versions of libraries are used. So this tutorial starts on a machine on which you just installed default Ubuntu 13.10.
I am using Pyinstaller as the next step. You would think that a Pyinstaller binary would be more or less independent of libraries, since the binary packages almost all needed libraries. Thus you would not need a clean build machine; a binary from the dev machine should work, and a little sanity testing on other platforms would show that. However, such sanity testing shows that Pyinstaller binary from 13.04 does NOT work on 13.10, some of the system libraries in the package crash!
But in apparent contradiction, Pyinstaller recommends that you build on the oldest version of the operating system that you have ‘laying around.’ Thus Pyinstaller is not a magic bullet.
Overview
Steps:
- get the packages needed for compiling Python bindings to Qt
- get missing Qt libraries
- fix a problem with PyQt’s makefile
- build PyQt and SIP from the origin vendor.
Get the packages needed for compiling PyQt Python bindings to Qt
- using Ubuntu Software Center (USC), install package ‘qt5-default’. This package set Qt5 to be the default when running Qt dev tools, instead of Qt4. This is an omnibus package, including many other packages. PyQt needs the header files to compile, and uses the qmake tool to determine which version of Qt you are using.
- using USC, install package ‘python-dev’. These are include header files for Python.
Get optional Qt libraries
My app uses QtSvg, an optional library of Qt. For some reason, Ubuntu13.10 doesn’t include it.
Using USC, install package ‘libqt5svg5’ and ‘libqt5svg5-dev’.
If you fail to do this first, PyQt5 will successfully build, but not build bindings to QtSvg. Then later, your app will fail to import PyQt5.QtSvg, and you will need to rebuild PyQt5. Apparently PyQt5 builds bindings to optional Qt libraries based on whether their header files are present (not whether the libraries are present.) Thus you need the -dev package.
There are many other optional Qt libraries. Qt5 has moved towards having more optional libraries.
Fix a problem with PyQt’s makefile
PyQt’s makefile assumes python headers are in /usr/local/include/python27. This is a typical problem among Linux distributions: some install certain things to /usr/local, some install to /usr. Ubuntu does the latter, while PyQt makefile assumes the former.
Here we create a soft link:
ln -s /usr/include/python2.7 /usr/local/include/python2.7
Note that the second path is the link that is created, to the target given by the first path.
Build PyQt and SIP from the origin vendor.
PyQt depends on SIP.
Build SIP
- Download SIP from the vendor.
- Extract
- cd to that directory
Follow the vendor’s instructions, the default:
python configure.py make sudo make install
Build PyQt
- Download PyQt5 from the vendor.
- Extract
- cd to that directory
Follow the vendor’s instructions, slightly augmented:
python configure.py --sip-incdir ../sip*/siplib make - j 2 sudo make install
This assumes you built SIP in a parallel directory to PyQt. I don’t know why installing SIP did not put its sip.h header where PyQt could find it. Possibly it was installed to /usr/local/include.
The make takes many minutes.
Note the makefile prints an error message about ‘strip’, at the end of its processing. The vendor advises to ignore it.
Testing
python
>>>import PyQt5.QtSvg