Python programs for Windows with py2exe

If you know me, you know that I don’t often acknowledge the existence of Windows as an OS worth my attention.  However, I’m working on some code for a group of people who are predominantly Windows users that, aside from their choice of OS, are pretty quality individuals.  Since I would certainly not spend my time writing a native win32 application, I decided to use Python, which is one of my preferred languages for Linux.

I knew that Python ran on Windows, but I didn’t realize how extensive the list of necessary add-on packages would be; I’m spoiled by modern Linux distributions.  For this app, I would need Python, pyGTK, and pySerial.  Those packages require the GTK runtime, the win32all package, pygobject, and pycairo.  Thus, any poor Windows user would be stuck installing a raft of packages totalling about 50MB (download size) before they could run the app.

I figured there had to be a better way.  I had considered getting the source for all of the python code and putting it into a single tree and rebuilding the installer to install them all at once, but that wouldn’t cover GTK and would be a bit of a pain.  After a bit of searching, I came across py2exe.

This nifty little tool extends the python distutils and gives you a new build target.  During the build process, it determines all of the required Python packages that your app will need and copies them into a distribution directory.  It then copies in the Python runtime itself, as well as any necessary DLLs to run.  Finally, it turns your toplevel .py file into a .exe.  Zip that up and post it.  All someone needs to do is extract it and run your .exe file.  How nice is that?

Given that pyGTK is rather large and complex, it didn’t go as smoothly as it should have.  I had to do two extra things: Add a list of required packages to assist the detection and copy in the GTK share files.  My setup.py ended up like this:

from distutils.core import setup
import py2exe

opts = {
“py2exe” : {
“includes” : “pango,atk,gobject,cairo,pangocairo”,
}
}

setup(windows=[“mainapp.py”], options=opts)

After building, you get a nice “dist/” (or, in the backwards Windows world, “dist”Smilie: ;) directory.  To complete the GTK distribution, I copied the share, etc, and lib directories from C:GTK into dist.  To cut down on the extra crap, I also deleted everything but “en” from the “share/locale” directory.  The result is a nice and neat little package that OS-challenged people can handle.  I think I’ll also need to figure out how MacOS distributes such things at some point, but I’m sure there will be less groaning and eye-rolling during that process.

Category(s): Codemonkeying
Tags: ,

Comments are closed.