Table Of Contents

Previous topic

Installing Mailman on Ubuntu

This Page

Bootstrapping Python Builds

It’s good practice to make the software projects that you develop be really easy for others to set up the environment on their machine.

Building Python projects can be great for this, but there is a bootstrapping problem. The Python tools that are used in packaging and building products assume that you have some bare minimim tools installed.

  1. The correct version of Python.
  2. Setuptools (which provides easy_install) and/or pip which provide Python egg dependency management.
  3. A virtualenv so packages can be installed without polluting the central install of Python.

I often use these two scripts (or variants of them) at the top level of my projects to bootstrap the environment. It’s good practice to test whether the right versions of tools are installed.


The usual way I do this is to commit the file into my source code control for my project - this means that there is one less install that needs to be done manually by the user. The script below assumes that this file can be found in the folder buildtools at the top of the project folder. (A Linux-only environment can use wget to download this file: Windows doesn’t have such a handy tool installed ubiquitously).

Paste the following into a .bat file:

@echo off
REM Bootstrap the environment for building a Python project

set PYVER=27
set VENV=pyenv
set VENVARGS=--system-site-packages --distribute

REM Test that Python is installed
IF exist c:\Python%PYVER%\nul (
    echo Using c:\Python%PYVER%.
) ELSE (
    echo Please install the Python in the default location: C:\Python%PYVER%

REM Build a virtualenv for this project
IF exist %VENV%\nul (
    echo The virtualenv '%VENV%' is built already
) ELSE (
    c:\Python%PYVER%\python.exe buildtools\ %VENVARGS% %VENV%
    IF errorlevel 1 GOTO FAILED

REM Activate this Python version

REM Using SCons as the build for the rest of the project is great
REM because it is based on Python. Install SCons into this environment.
easy_install SCons
IF errorlevel 1 GOTO FAILED

REM Now run the scons make, passing the rest of the command line.
scons %*

ECHO Build Failed.

Edit the PYVER and VENV variables to point to the Python version and the name of the virtualenv folder respectively. As the comments in the above script indicate, I often use SCons as the build system for a project, and so this tool in installed into the virtualenv.

Note the this script “activates” the virtualenv in the DOS shell that is being run, which is a great convenience in a development environment. This means that the executables like python and easy_install that are in the virtualenv are first on the PATH environment variable.

You might also want to edit the VENVARGS variable. The value of --system-site-packages means that the virtualenv created will still see the packages that are installed in the system-wide Python installation. Change it to --no-site-packages to isolate the virtualenv from the system-wide site packages.


Create a build shell script like this:

#! /bin/bash

# Bootstrap a virtualenv build

export PYVER=2.7
export VENV=pyenv
export VENVARGS=--system-site-packages --distribute

# Test that Python is installed
if [ -x /usr/bin/python$PYVER ] ; then
    echo Using Python$PYVER
    echo Please install Python $PYVER package
    exit 1

# Build a virtualenv for this project
if [ -d $VENV ] ; then
    echo The virtualenv '$VENV' is built already
    /usr/bin/python$PYVER $VENVARGS $VENV
    rm -f*

. $VENV/bin/activate

# Install SCons in this virtualenv to do the actual build
if [ -f $VENV/bin/scons ] ; then
   echo Found an installed SCons
    echo Installing SCons
    easy_install scons==2.2.0
export SCONS_LIB_DIR=pyenv/lib/python$PYVER/site-packages/scons-2.2.0-py$PYVER.egg/scons-2.2.0/

# Run scons to do the rest of the build
scons $*

# Tell the user to activate the virtualenv in their shell.
echo You should activate the virtualenv Python now. Run:
echo . $VENV/bin/activate

Because wget is always available on Linux machines, the doesn’t have to be committed into the project’s source code if your project is only supposed to run on Linux.