Each Answer to this Q is separated by one/two green lines.
How can I distribute a standalone Python application in Linux?
I think I can take for granted the presence of a recent Python interpreter in any modern distribution. The problem is dealing with those libraries that do not belong to the standard library, i.e. wxPython, scipy, python cryptographic toolkit, reportlab, and so on.
Is there a working Linux counterpart to, say, py2exe (which, by the way, I have never tried)?
Is there a free, opensource one?
Create a deb (for everything Debian-derived) and an rpm (for Fedora/SuSE). Add the right dependencies to the packaging and you can be reasonably sure that it will work.
You can use cx_Freeze to do this. It’s just like py2exe (bundles together the interpreter and and startup script and all required libraries and modules), but works on both Linux and Windows.
It collects the dependencies from the environment in which it is run, which means that they need to be suitable for the destination as well. If you’re doing something like building on 32 bit Debian and deploying on another 32 bit Debian, then that’s fine. You can handle 32/64 bit differences by building multiple versions in appropriate environments (e.g. 32 bit and 64 bit chroots) and distributing the appropriate one. If you’re wanting something more generic (e.g. build on Debian, deploy on any distribution), then this gets a bit murky, depending on exactly what your dependencies are.
If you’re doing a fairly straightforward distribution (i.e. you know that your build environment and deploy environments are similar), then this avoids the rather complex rpm/deb/egg/etc step (using cx_Freeze is very easy, especially if you’re familiar with py2exe). If not, then anything from rolling your own dependancy installer to deb/rpm/egg/etc building will work, depending on how much work you want to do, how much flexibility with required versions you want to offer, and what the dependencies are.
You might want to look at the dependency declarations in setuptools. This might provide a way to assure that the right packages are either available in the environment or can be installed by someone with appropriate privileges.
You can’t easily do it in a distribution-neutral format. The only reliable dependency tracking mechanisms are built into the package management systems on the distributions and will vary from distribution to distribution. You’ll effectively have to do rpm for fedora, debs for ubuntu and debian etc.
Py2exe works fine on Windows. It builds a distribution with all of the necessary DLL’s and a wrapper for the python interpreter that starts your program. It’s fairly straightforward to install – just drop it in a directory – so making a msi file for it is trivial.
Setuptools is overkill for me since my program’s usage is quite limited, so here’s my homegrown alternative.
I bundle a “third-party” directory that includes all prerequisites, and use site.addsitedir so they don’t need to be installed globally.
# program startup code import os import sys import site path = os.path.abspath(os.path.dirname(__file__)) ver="python%d.%d" % sys.version_info[:2] thirdparty = os.path.join(path, 'third-party', 'lib', ver, 'site-packages') site.addsitedir(thirdparty)
Most of my prereqs have setup.py installers. Each bundled module gets its own “install” process, so any customized stuff (e.g. ./configure) can be run automatically. My install script runs this makefile as part of the install process.
# sample third-party/Makefile PYTHON_VER = `python -c "import sys; \ print 'python%d.%d' % sys.version_info[:2]"` PYTHON_PATH = lib/$(PYTHON_VER)/site-packages MODS = egenix-mx-base-3.0.0 # etc .PHONY: all init clean realclean $(MODS) all: $(MODS) $(MODS): init init: mkdir -p bin mkdir -p $(PYTHON_PATH) clean: rm -rf $(MODS) realclean: clean rm -rf bin rm -rf lib egenix-mx-base-3.0.0: tar xzf [email protected] cd [email protected] && python setup.py install --prefix=.. rm -rf [email protected]
I think you can fairly safely take for granted python support on most modern Linux distributions – for the ones without it as long as a sane error message is given, users should probably be able to work how to get it on their own (you can use a simple bash startup script for this):
#!/bin/bash if [ -e /usr/bin/python ] then echo "Python found!" else echo "Python missing!" fi
Python is notoriously flaky with respect to different setups. The only sane way to deploy a python app is to ship the whole bundle of interpreter and libraries that you are relying on with your code. That will most likely work.
Update 2019: I stand by this. Virtualenv is a way of packaging libraries and interpreters together. Tox is a testing tool to test that interpreter/dependency matrix. Docker is a widely used way of then deploying the bundle.