Cross Compiling Python Extensions
If you are working with Python in an embedded environment, you will enventually want to build a Python extension with a cross tool chain. These instructions work both with Open Embedded and the DENX ELDK. If you need to go cross compile Python 2.5, 2.6 or 3.1. ELDK and Open Embedded include a version of Python pre-done for you. You will need a version of Python for the build system that matches your target enviroment.
On the host machine install setuptools and distutilscross. If you are using Python 2.6.3 you probably need to also install distribute which is a replacement for setuptools that also happens to fix a conflict between setuptools 0.6c9 and Python 2.6.3 (There is an update of setuptools coming soon too. See the update below). If you want to use virtualenv and distribute together, you might need to use virtualenv-distribute, a fork of virtualenv that uses distribute instead of setuptools.
Distutilscross is a package that uses setuptools to monkey patch an extra parameter, –cross-compile, into the distutils build command. The net result is that you can set your cross compile environment variables, plus PYTHONXCPREFIX and do python setup.py build -x to get your extensions to compile.
Lets take ELDK as an example.
$ export PYTHONXCPREFIX=/opt/eldk/ppc_4xxFP/usr
$ export CROSS_COMPILE=ppc_4xxFP-
$ export CC="${CROSS_COMPILE}gcc -pthread"
$ export LDSHARED="${CC} -shared"
$ export LDFLAGS="-L/opt/eldk/ppc_4xxFP/usr/lib -L/opt/eldk/ppc_4xxFP/lib"
$ python setup.py build -x bdist_egg --plat-name=linux-ppcWe always need to define PYTHONXCPREFIX and LDFLAGS. PYTHONXCPREFIX tells the -x (or –cross-compile) where your target built Python is. Mostly it is looking for the options used at build time from $PREFIX/lib/python2.x/config/Makefile. This will also set the compile up to use the target Python’s headers. We need to set LDFLAGS as above because Distutils always generates the link directory options as pointing to the Host Python’s install location.
We also need to set CC and LDSHARED because the compiler guessed out of the target Python Makefile is wrong for ELDK. If you are compiling C++ code you would also need to set the CXX environment variable.
Once you have the egg built, you can copy it over to a package directory (read an auto-indexed directory on a web server) and install it from your target using:
$ easy_install -f http://mylocalpackageplace/nest package_name
Concrete example time, what do you need in order to build the deps for and install TurboGears 2. You need the following packages:
zope.interface, Genshi, and simplejson. ELDK’s installation of Python 2.5 does not seem to come with sqlite so you will either need to do a new cross compile of python or get a separate install of the sqlite library. Once you have your binary eggs built using the above command copy them to your local http server, I’ll use 192.168.1.99. You need to follow the Manual Installation method for TurboGears but when you get to Install TurboGears 2 add “-f http://192.168.1.99/nest/” to the command line so that you get:
(tg2env)$ easy_install -i http://www.turbogears.org/2.0/downloads/current/index -f http://192.168.1.99/nest/ tg.devtools
This is sufficient for most normal extension building situations. Unfortunately there are some extensions that use autotools and python-config instead of distutils (dbus-python and omniORBpy come to mind). Autotools should let you override the critical settings but I would like to see the situation improve.
Let me know if you have ideas on how to make Python development in an embedded environment better.
Update: PJE, the author of setuptools, has given notice of the impending release of setuptools 6c10 which fixes many bugs, including the Python 2.6.3 compile bug. See his comment below.
October 17th, 2009 at 2:30 am
Wow, this is a lot easier than it was a few years ago.
What is your target platform (like the actual application, not the environment)
? What other ones are you going to target with this?
October 17th, 2009 at 1:45 pm
FYI, setuptools 0.6c10 includes a fix for the Python 2.6.3 problem (along with numerous other bug fixes), and will be released Monday. You can also get it now via SVN, using “easy_install setuptools==dev06″.
October 17th, 2009 at 6:11 pm
Micheal: As you might be able to guess from my examples, I am working on a TurboGears 2 app on a linux-ppc target.
Since I am an independent contractor, anything else I do would be based on customer needs.
March 6th, 2010 at 6:35 pm
This is great! Thanks for your post. I am just starting django and this got me straight.
June 1st, 2010 at 1:22 pm
Do you know how to cross-compile pyserial package?
June 4th, 2010 at 9:47 am
There is no need to cross build pyserial, it is a python only package (i.e. it does not contain any c/c++ code). If you want an egg you can use:
python setup.py bdist_eggThe egg will then be in the dist directory (might be in a sub directory of dist).