Compilación cruzada de Python

written by uve 8 March 2011

Hace pocos días escribía acerca de como crear un toolchain para compilar para una arquitectura distinta: MIPS. Ahora voy brevemente a contar como podemos compilar un intéprete de Python para un dispositivo integrado.

El principal problema que hay es que para compilar para arquitecturas como MIPS o ARM es necesario un parche, por lo que la compilación directa no es posible. Yo he seguido este tutorial y he usado la misma versión, Python 2.7.1, y el mismo parche y todo ha funcionado perfectamente.

Veamos los pasos que hay seguir. Lo primero es descargar el código fuente de Python 2.7.1. Una vez descargado, lo extraemos y hacemos una compilación nativa para nuestra arquitectura:

$ tar xjvf Python-2.7.1.tar.bz2
$ ./configure
$ make python Parser/pgen

Una vez generados estos binarios, los guardamos con un nombre distinto, por ejemplo añadiéndole la palabra host (es el nombre que se suele usar):

$ mv python hostpython
$ mv Parser/pgen Parser/hostpgen

Y ahora preparamos el entorno para la compilación cruzada:

$ make distclean
$ CC=mips-unknown-linux-uclibc-gcc CXX=mips-unknown-linux-uclibc-g++ AR=mips-unknown-linux-uclibc-ar RANLIB=mips-unknown-linux-uclibc-ranlib ./configure --host=mips-linux --target=mips-linux
$ make HOSTPYTHON=./hostpython HOSTPGEN=./Parser/hostpgen BLDSHARED="mips-unknown-linux-uclibc-gcc -shared" CROSS_COMPILE=mips-linux- CROSS_COMPILE_TARGET=yes

Si fijamos bien, los pasos son los mismos que antes, pero hemos cambiado algunas variables de entorno: CC, CXX, AR, RANDLIB para el configure y HOSTPYTHON, HOSTPGEN, BLDSHARED, CROSS_COMPILE y CROSS_COMPILE_TARGET. Además, las herramientas que he usado son las del toolchain que generé, por lo que el intérprete se podrá ejecutar en una arquitectura MIPS.

Es bastante probable, tal y como me pasó a mi, que obtengamos el siguiente error:

Include/pyport.h:243:13: error: #error “This platform’s pyconfig.h needs to define PY_FORMAT_LONG_LONG

Por tanto es necesario aplicar el parche y repetir los pasos anteriores. Lo primero es descargar el fichero python-2.7.1-cross-compile.patch y aplicarlo:

$ patch -p1 < python-2.7.1-cross-compile.patch

Es posible que durante la compilación aparezca un error como este:

...
mips-unknown-linux-uclibc-ranlib libpython2.7.a
mips-unknown-linux-uclibc-gcc  -Xlinker -export-dynamic -o python \
            Modules/python.o \
            libpython2.7.a -lpthread -ldl  -lpthread -lutil   -lm 
libpython2.7.a(posixmodule.o): In function `posix_utime':
/home/vruiz/Downloads/Python-2.7.1/./Modules/posixmodule.c:2901: warning: the use of LEGACY `utimes' is discouraged, use `utime'
  File "./setup.py", line 316
    self.announce('*** WARNING: renaming "%s" since importing it'
       ^
IndentationError: expected an indented block
make: *** [sharedmods] Error 1

Es por un pequeño error en el parche. Es tan sencillo como editar el fichero setup.py, en la línea 316 y añadir 4 espacios. Volvemos a lanzar make y todo arreglado.

Una vez terminado, ya tenemos listo nuestro intérprete:

$ ls -l
...
-rwxr-xr-x  1 vruiz vruiz 4016444 mar  8 15:54 python
...
$ file python
python:
ELF 32-bit MSB executable, MIPS, MIPS-I version 1 (SYSV), dynamically
linked (uses shared libs), with unknown capability 0x41000000 =
0xf676e75, with unknown capability 0x10000 = 0x70403, not stripped

Source

http://www.cnx-software.com/2011/02/04/cross-compiling-python-for-mips-and-arm-platforms/

Tags

La teoría es cuando crees saber algo, pero no funciona.
La práctica es cuando algo funciona, pero no sabes por qué.
Los programadores combinan la teoría y la práctica:
Nada funciona y no saben por qué.