Blog Post

Installing Python scripts from automake...

Trond Norbye of Couchbase Published

I've been working on making it easier for developers to compile and install Membase, and today I learned some more automake magic. I'm one of those developers who don't want to spend a lot of time working on the build system, I want to spend my time working on the code. At the same time I don't want to do unnecessary boring manual work that the build system should do for me.

Parts of Membase are implemented in Python, and I've been trying to figure out how to install those pieces. I don't like to mess up the /bin directory with "library" files, so I needed a way to package the Python bits better. I've been using a wrapper script that sets the PYTHONPATH variable earlier, but I've never tried to integrate that into an automake generated makefile.

As always I started out asking google for help, but I didn't end up with a good and easy example so I ended up reading through the automake manual. It turns out that it's fairly easy to do exactly what I want, so I decided to share the knowledge in a blog post :-)

We don't want to hardcode the path to our binary anywhere, so the first thing we need to do is to update configure.ac to also generate our wrapper script:


AC_CONFIG_FILES(Makefile python_wrapper)

I've got multiple programs implemented with Python, and I don't want to create a ton of wrappers, so my python_wrapper.in looks like:


#! /bin/sh
if test -z "${PYTHONPATH}"; then
   PYTHONPATH=@libdir@/python
else
   PYTHONPATH=@libdir@/python:${PYTHONPATH}
fi
export PYTHONPATH
exec @libdir@/python/`basename $0`.py "$@"

This means that if I install this script as /opt/membase/bin/stats, it will try to execute /opt/membase/lib/python/stats.py with the same arguments. So let's go ahead and add a rule to Makefile.am to generate the scripts with the correct names:


PYTHON_TOOLS=stats
${PYTHON_TOOLS}: python_wrapper
    cp $< $@

BUILT_SOURCES += ${PYTHON_TOOLS}
CLEANFILES+= ${PYTHON_TOOLS}
bin_SCRIPTS+= ${PYTHON_TOOLS}

Now we've got the wrapper script in place, and we've generated all of the scripts to start our programs. The next thing up would be to create the destination directory for the python bits, and install all of them there. To do so we need to create a variable that ends with "dir" to contain the name of the directory. Let's name our "pythonlibdir" and put it in a subdirectory named python of the specified libdir:


pythonlibdir=$(libdir)/python


Finally we need to list all of the files we want to go there:


pythonlib_DATA= \
                mc_bin_client.py \
                mc_bin_server.py \
                memcacheConstants.py
 
pythonlib_SCRIPTS= \
                stats.py \

The reason I use pythonlib_SCRIPTS for the last one is because I want the execute bit set on file.