Build Python from source... with optional dependencies

In order to try out Python 3.6's new format strings -- no, really -- I wanted to build myself an alpha version of CPython. The canonical source is on a Mercurial repository; there's also a mirror on Github, which I chose to use for this, but either would work identically.

Grabbing the source is easy enough -- just git clone or the equivalent for the Mercurial repository.

The typical method of building and installing a source package on *nix systems is the following:

./configure && make && sudo make install

I made a couple of minor adjustments to this for my system. First of all, I wanted to install /usr/local (so my binary would be in /usr/local/bin/python3.6, etc.), so I added the argument --prefix=/usr/local to the configure script.

Secondly, as this was an alpha version, I didn't want it to overwrite my main python3 link; I just wanted a version-specific python3.6. To do this I replaced install with altinstall -- as per this StackOverflow answer, altinstall does everything install does, just without the versionless manpages and binaries.

Now came the tricky part: installing the dependencies. "Optional dependencies" might seem like an oxymoron, but it's referring to optional parts of the compiler that depend on external libraries, and will quietly fail if those libraries aren't found.

I wanted a full install of the compiler with all the optional dependencies, so I looked for a list of them...

... and couldn't find one. Maybe I've been looking in the wrong place, but there doesn't seem to be a canonical list of Python's dependencies. The documentation told me two interesting things, however:

  • A core install of CPython and its interpreter requires NO additional libraries; and
  • To install dependencies on Ubuntu/Debian systems, use apt-get build-dep $PYTHONVERSION

There were equivalents for OSX (using XCode) and Windows. But I'm not a fan of that second approach -- it relies on the Ubuntu repositories being up-to-date, which isn't always the case. And it seems... sort of like cheating?

Anyway, I couldn't find another way of doing it, so that's what I settled with. In fact, the repositories weren't up-to-date; I had to use "python3.4" for the python version. Luckily, it didn't seem like any dependencies had been introduced, and a quick scan of "what's new in X" pages in the Python docs confirmed it.

For the record, here's the packages that sudo apt-get build-dep python3.4 installed on my Ubuntu 14.04 server.

autoconf blt blt-dev debhelper dh-apparmor docutils-common libbluetooth-dev libbz2-dev libdb-dev libdb5.3-dev libfontconfig1-dev libfreetype6-dev libgdbm-dev libice-dev libjs-jquery libjs-sphinxdoc libjs-underscore liblzma-dev libmpdec-dev libncursesw5-dev libpng12-dev libreadline6-dev libsigsegv2 libsm-dev libsqlite3-dev libtcl8.6 libtinfo-dev libtk8.6 libxext-dev libxft-dev libxrender-dev libxss-dev libxt-dev m4 po-debconf python-docutils python-jinja2 python-markupsafe python-pygments python-roman python-sphinx quilt sharutils sphinx-common tcl tcl-dev tcl8.6 tcl8.6-dev tk tk-dev tk8.6 tk8.6-dev x11proto-render-dev x11proto-scrnsaver-dev  

Some of them are pretty familiar: the PNG, SQLite, Curses and a few other libraries are ones I've run into before when doing image processing, database interaction and the like. But I'll leave it till another time to figure out just why a module in the CPython interpreter depends on libjs-jquery...

Apt told me this would use an additional 55.5mb of disk space. This command finished the job:

./configure --prefix=/usr/local && make && sudo make altinstall

And I had a working Python 3.6 (alpha 1) interpreter!

Python Interpreter