Python on Android

Note: This post is out of date. If you'd like to run Python on your Android device, please see my Android Scripting Environment project.

Here's an early Christmas present for all those Python fanatics (self included) out there! With a lot of help from my friends (thanks Manuel and Thomas!) I managed to install Python 2.4.5 on my G1. It's still rough around the edges, but I think it's a good start. Klaus Reimer has a nice overview of how to cross-compile Python. My instructions borrow a lot from his.
  • Download and build the Android source. These directions assume that you have installed the source to /android_src.
  • Download and build the Python 2.4.5 source. These directions assume that you have installed the source to /python_src.
  • Make copies of python and pgen for use later in the build process then clean up.
$ cd /python_src
$ cp python hostpython
$ cp Parser/pgen Parser/hostpgen
$ make distclean
  • Apply the following patch to the Python source.
diff -r -c -b Python-2.4.5/Makefile.pre.in Python-2.4.5-android/Makefile.pre.in
*** Python-2.4.5/Makefile.pre.in Sun Oct 8 19:41:25 2006
--- Python-2.4.5-android/Makefile.pre.in Fri Dec 19 10:02:17 2008
***************
*** 166,171 ****
--- 166,172 ----

PYTHON= python$(EXE)
BUILDPYTHON= python$(BUILDEXE)
+ HOSTPYTHON= ./$(BUILDPYTHON)

# === Definitions added by makesetup ===

***************
*** 192,197 ****
--- 193,199 ----
##########################################################################
# Parser
PGEN= Parser/pgen$(EXE)
+ HOSTPGEN= $(PGEN)

POBJS= \
Parser/acceler.o \
***************
*** 324,331 ****
# Build the shared modules
sharedmods: $(BUILDPYTHON)
case $$MAKEFLAGS in \
! *-s*) $(RUNSHARED) CC='$(CC)' LDSHARED='$(BLDSHARED)' OPT='$(OPT)' ./$(BUILDPYTHON) -E $(srcdir)/setup.py -q build;; \
! *) $(RUNSHARED) CC='$(CC)' LDSHARED='$(BLDSHARED)' OPT='$(OPT)' ./$(BUILDPYTHON) -E $(srcdir)/setup.py build;; \
esac

# buildno should really depend on something like LIBRARY_SRC
--- 326,333 ----
# Build the shared modules
sharedmods: $(BUILDPYTHON)
case $$MAKEFLAGS in \
! *-s*) $(RUNSHARED) CC='$(CC)' LDSHARED='$(BLDSHARED)' OPT='$(OPT)' $(HOSTPYTHON) -E $(srcdir)/setup.py -q build;; \
! *) $(RUNSHARED) CC='$(CC)' LDSHARED='$(BLDSHARED)' OPT='$(OPT)' $(HOSTPYTHON) -E $(srcdir)/setup.py build;; \
esac

# buildno should really depend on something like LIBRARY_SRC
***************
*** 455,461 ****


$(GRAMMAR_H) $(GRAMMAR_C): $(PGEN) $(GRAMMAR_INPUT)
! -$(PGEN) $(GRAMMAR_INPUT) $(GRAMMAR_H) $(GRAMMAR_C)

$(PGEN): $(PGENOBJS)
$(CC) $(OPT) $(LDFLAGS) $(PGENOBJS) $(LIBS) -o $(PGEN)
--- 457,463 ----


$(GRAMMAR_H) $(GRAMMAR_C): $(PGEN) $(GRAMMAR_INPUT)
! -$(HOSTPGEN) $(GRAMMAR_INPUT) $(GRAMMAR_H) $(GRAMMAR_C)

$(PGEN): $(PGENOBJS)
$(CC) $(OPT) $(LDFLAGS) $(PGENOBJS) $(LIBS) -o $(PGEN)
***************
*** 748,767 ****
done; \
done
$(INSTALL_DATA) $(srcdir)/LICENSE $(DESTDIR)$(LIBDEST)/LICENSE.txt
! PYTHONPATH=$(DESTDIR)$(LIBDEST) $(RUNSHARED) \
! ./$(BUILDPYTHON) -Wi -tt $(DESTDIR)$(LIBDEST)/compileall.py \
-d $(LIBDEST) -f \
-x 'badsyntax|site-packages' $(DESTDIR)$(LIBDEST)
! PYTHONPATH=$(DESTDIR)$(LIBDEST) $(RUNSHARED) \
! ./$(BUILDPYTHON) -Wi -tt -O $(DESTDIR)$(LIBDEST)/compileall.py \
-d $(LIBDEST) -f \
-x 'badsyntax|site-packages' $(DESTDIR)$(LIBDEST)
-PYTHONPATH=$(DESTDIR)$(LIBDEST) $(RUNSHARED) \
! ./$(BUILDPYTHON) -Wi -t $(DESTDIR)$(LIBDEST)/compileall.py \
-d $(LIBDEST)/site-packages -f \
-x badsyntax $(DESTDIR)$(LIBDEST)/site-packages
-PYTHONPATH=$(DESTDIR)$(LIBDEST) $(RUNSHARED) \
! ./$(BUILDPYTHON) -Wi -t -O $(DESTDIR)$(LIBDEST)/compileall.py \
-d $(LIBDEST)/site-packages -f \
-x badsyntax $(DESTDIR)$(LIBDEST)/site-packages

--- 750,769 ----
done; \
done
$(INSTALL_DATA) $(srcdir)/LICENSE $(DESTDIR)$(LIBDEST)/LICENSE.txt
! -PYTHONPATH=$(DESTDIR)$(LIBDEST) $(RUNSHARED) \
! $(HOSTPYTHON) -Wi -tt $(DESTDIR)$(LIBDEST)/compileall.py \
-d $(LIBDEST) -f \
-x 'badsyntax|site-packages' $(DESTDIR)$(LIBDEST)
! -PYTHONPATH=$(DESTDIR)$(LIBDEST) $(RUNSHARED) \
! $(HOSTPYTHON) -Wi -tt -O $(DESTDIR)$(LIBDEST)/compileall.py \
-d $(LIBDEST) -f \
-x 'badsyntax|site-packages' $(DESTDIR)$(LIBDEST)
-PYTHONPATH=$(DESTDIR)$(LIBDEST) $(RUNSHARED) \
! $(HOSTPYTHON) -Wi -t $(DESTDIR)$(LIBDEST)/compileall.py \
-d $(LIBDEST)/site-packages -f \
-x badsyntax $(DESTDIR)$(LIBDEST)/site-packages
-PYTHONPATH=$(DESTDIR)$(LIBDEST) $(RUNSHARED) \
! $(HOSTPYTHON) -Wi -t -O $(DESTDIR)$(LIBDEST)/compileall.py \
-d $(LIBDEST)/site-packages -f \
-x badsyntax $(DESTDIR)$(LIBDEST)/site-packages

***************
*** 856,862 ****
# Install the dynamically loadable modules
# This goes into $(exec_prefix)
sharedinstall:
! $(RUNSHARED) ./$(BUILDPYTHON) -E $(srcdir)/setup.py install \
--prefix=$(prefix) \
--install-scripts=$(BINDIR) \
--install-platlib=$(DESTSHARED) \
--- 858,864 ----
# Install the dynamically loadable modules
# This goes into $(exec_prefix)
sharedinstall:
! $(RUNSHARED) $(HOSTPYTHON) -E $(srcdir)/setup.py install \
--prefix=$(prefix) \
--install-scripts=$(BINDIR) \
--install-platlib=$(DESTSHARED) \
diff -r -c -b Python-2.4.5/Modules/pwdmodule.c Python-2.4.5-android/Modules/pwdmodule.c
*** Python-2.4.5/Modules/pwdmodule.c Wed Sep 27 21:17:32 2006
--- Python-2.4.5-android/Modules/pwdmodule.c Fri Dec 19 10:26:14 2008
***************
*** 77,83 ****
#ifdef __VMS
SETS(setIndex++, "");
#else
! SETS(setIndex++, p->pw_gecos);
#endif
SETS(setIndex++, p->pw_dir);
SETS(setIndex++, p->pw_shell);
--- 77,83 ----
#ifdef __VMS
SETS(setIndex++, "");
#else
! SETS(setIndex++, "");//p->pw_gecos);
#endif
SETS(setIndex++, p->pw_dir);
SETS(setIndex++, p->pw_shell);
diff -r -c -b Python-2.4.5/Modules/socketmodule.c Python-2.4.5-android/Modules/socketmodule.c
*** Python-2.4.5/Modules/socketmodule.c Tue Oct 10 18:20:41 2006
--- Python-2.4.5-android/Modules/socketmodule.c Fri Dec 19 17:51:36 2008
***************
*** 61,66 ****
--- 61,67 ----

*/

+ #define INET_ADDRSTRLEN 16
#ifdef __APPLE__
/*
* inet_aton is not available on OSX 10.3, yet we want to use a binary
diff -r -c -b Python-2.4.5/Objects/fileobject.c Python-2.4.5-android/Objects/fileobject.c
*** Python-2.4.5/Objects/fileobject.c Tue Jan 23 16:09:19 2007
--- Python-2.4.5-android/Objects/fileobject.c Fri Dec 19 16:47:32 2008
***************
*** 1,5 ****
--- 1,6 ----
/* File object implementation */

+ #include "/android_src/bionic/libc/stdio/clrerr.c"
#include "Python.h"
#include "structmember.h"

diff -r -c -b Python-2.4.5/Python/pystrtod.c Python-2.4.5-android/Python/pystrtod.c
*** Python-2.4.5/Python/pystrtod.c Tue Jun 8 20:52:54 2004
--- Python-2.4.5-android/Python/pystrtod.c Fri Dec 19 10:18:11 2008
***************
*** 54,61 ****

fail_pos = NULL;

! locale_data = localeconv();
! decimal_point = locale_data->decimal_point;
decimal_point_len = strlen(decimal_point);

assert(decimal_point_len != 0);
--- 54,61 ----

fail_pos = NULL;

! //locale_data = localeconv();
! decimal_point = '.';//locale_data->decimal_point;
decimal_point_len = strlen(decimal_point);

assert(decimal_point_len != 0);
***************
*** 218,225 ****

PyOS_snprintf(buffer, buf_len, format, d);

! locale_data = localeconv();
! decimal_point = locale_data->decimal_point;
decimal_point_len = strlen(decimal_point);

assert(decimal_point_len != 0);
--- 218,225 ----

PyOS_snprintf(buffer, buf_len, format, d);

! //locale_data = localeconv();
! decimal_point = '.';//locale_data->decimal_point;
decimal_point_len = strlen(decimal_point);

assert(decimal_point_len != 0);
diff -r -c -b Python-2.4.5/setup.py Python-2.4.5-android/setup.py
*** Python-2.4.5/setup.py Sun Oct 8 19:41:25 2006
--- Python-2.4.5-android/setup.py Fri Dec 19 17:26:29 2008
***************
*** 15,21 ****
from distutils.command.install_lib import install_lib

# This global variable is used to hold the list of modules to be disabled.
! disabled_module_list = []

def add_dir_to_list(dirlist, dir):
"""Add the directory 'dir' to the list 'dirlist' (at the front) if
--- 15,33 ----
from distutils.command.install_lib import install_lib

# This global variable is used to hold the list of modules to be disabled.
! disabled_module_list = [
! '_ctypes',
! '_curses',
! '_curses_panel',
! '_locale',
! '_ssl',
! 'crypt',
! 'linuxaudiodev',
! 'nis',
! 'ossaudiodev',
! 'readline',
! 'zlib',
! ]

def add_dir_to_list(dirlist, dir):
"""Add the directory 'dir' to the list 'dirlist' (at the front) if
***************
*** 199,204 ****
--- 211,218 ----
self.announce('WARNING: skipping import check for Cygwin-based "%s"'
% ext.name)
return
+ if os.environ.get('CROSS_COMPILE') == 'yes':
+ return
ext_filename = os.path.join(
self.build_lib,
self.get_ext_filename(self.get_ext_fullname(ext.name)))
  • Download agcc.
  • Make a copy of agcc called ag++ and apply the following patch.
*** agcc 2008-11-06 18:22:48.000000000 +0100
--- ag++ 2008-12-19 21:19:21.000000000 +0100
***************
*** 32,41 ****

# Dance around to find the actual android toolchain path (it's very
# deep, so links on $PATH are going to be common.
! my $GCC = `which arm-eabi-gcc`;
$GCC = qx(cd `dirname $GCC`; /bin/pwd);
chomp $GCC;
! die "bad arm-eabi-gcc path" if $GCC !~ /(.*)\/prebuilt\//;
my $DROID = $1;

my $ALIB = "$DROID/out/target/product/generic/obj/lib";
--- 32,41 ----

# Dance around to find the actual android toolchain path (it's very
# deep, so links on $PATH are going to be common.
! my $GCC = `which arm-eabi-g++`;
$GCC = qx(cd `dirname $GCC`; /bin/pwd);
chomp $GCC;
! die "bad arm-eabi-g++ path" if $GCC !~ /(.*)\/prebuilt\//;
my $DROID = $1;

my $ALIB = "$DROID/out/target/product/generic/obj/lib";
***************
*** 174,180 ****
if($have_src and $mode ne "-E") { $need_cpp = $need_compile = 1; }

# Assemble the command:
! my @cmd = ("arm-eabi-gcc");
if($mode ne "DEFAULT") { @cmd = (@cmd, $mode); }
if(defined $out) { @cmd = (@cmd, "-o", $out); }
if($need_cpp) { @cmd = (@cmd, @include_paths, @preprocess_args); }
--- 174,180 ----
if($have_src and $mode ne "-E") { $need_cpp = $need_compile = 1; }

# Assemble the command:
! my @cmd = ("arm-eabi-g++");
if($mode ne "DEFAULT") { @cmd = (@cmd, $mode); }
if(defined $out) { @cmd = (@cmd, "-o", $out); }
if($need_cpp) { @cmd = (@cmd, @include_paths, @preprocess_args); }
  • Add agcc and ag++ to your path.
  • Add /android_src/prebuilt/linux-x86/toolchain/arm-eabi-4.2.1/bin to your path (the Android toolchain).
  • Add /android_src/out/host/linux-x86/bin to your path (the Android development tools).
  • Reconfigure Python for Android.
$ CROSS_COMPILE=yes CXX=ag++ CC=agcc AR=arm-eabi-ar \
RANLIB=arm-eabi-ranlib LD=arm-eabi-ld AS=arm-eabi-as \
STRIP=arm-eabi-strip ./configure --host=linux --build=arm-linux --prefix=/data
  • Remove the posix module from the Makefile and from /python_src/Modules/config.c using the following patch.
*** Python-2.4.5/Makefile Fri Dec 19 22:21:20 2008
--- Python-2.4.5-android/Makefile Fri Dec 19 22:23:50 2008
***************
*** 21,27 ****

# === Variables set by makesetup ===

! MODOBJS= Modules/threadmodule.o Modules/signalmodule.o Modules/posixmodule.o Modules/errnomodule.o Modules/pwdmodule.o Modules/_sre.o Modules/_codecsmodule.o Modules/zipimport.o Modules/symtablemodule.o Modules/xxsubtype.o
MODLIBS= $(LOCALMODLIBS) $(BASEMODLIBS)

# === Variables set by configure
--- 21,27 ----

# === Variables set by makesetup ===

! MODOBJS= Modules/threadmodule.o Modules/signalmodule.o Modules/errnomodule.o Modules/pwdmodule.o Modules/_sre.o Modules/_codecsmodule.o Modules/zipimport.o Modules/symtablemodule.o Modules/xxsubtype.o
MODLIBS= $(LOCALMODLIBS) $(BASEMODLIBS)

# === Variables set by configure
*** Python-2.4.5/Modules/config.c Fri Dec 19 22:21:20 2008
--- Python-2.4.5-android/Modules/config.c Fri Dec 19 22:26:06 2008
***************
*** 21,27 ****

extern void initthread(void);
extern void initsignal(void);
! extern void initposix(void);
extern void initerrno(void);
extern void initpwd(void);
extern void init_sre(void);
--- 21,27 ----

extern void initthread(void);
extern void initsignal(void);
! //extern void initposix(void);
extern void initerrno(void);
extern void initpwd(void);
extern void init_sre(void);
***************
*** 40,46 ****

{"thread", initthread},
{"signal", initsignal},
! {"posix", initposix},
{"errno", initerrno},
{"pwd", initpwd},
{"_sre", init_sre},
--- 40,46 ----

{"thread", initthread},
{"signal", initsignal},
! // {"posix", initposix},
{"errno", initerrno},
{"pwd", initpwd},
{"_sre", init_sre},
  • Build and install Python to a local directory.
$ make install prefix=./python-android HOSTPYTHON=./hostpython \
HOSTPGEN=./Parser/hostpgen BLDSHARED="agcc -shared" CROSS_COMPILE=yes
  • Remove some unnecessary files and push Python to your G1 or emulator.
$ cd ./python-android
$ rm -rf man include lib/python2.4/test
$ find . -name '*.pyc' -exec rm {} \;
$ find . -name '*.pyo' -exec rm {} \;
$ find . -type d -not -name '.' | perl -pe 's,\./,/data/,' | xargs -L1 adb shell mkdir
$ adb push . data
And here it is.


Update
I've uploaded the python2.4 binary I built for Android. It's missing lots of libraries, but it runs :) I haven't corrected the build instructions yet, but I'll hopefully get to that soon.

23 comments:

  1. The goggles ... they do nothing!

    But seriously, kudos to you and the others for hacking this together. I'll definitely be following in your footsteps shortly.

    Will

    ReplyDelete
  2. My understanding is a little hazy but I assume this requires a dev edition or a rooted G1?

    ReplyDelete
  3. I dunno man, the whole thing seems a bit confusing to me!

    Jess
    www.anonymity.cz.tc

    ReplyDelete
  4. I am only an egg, but this looks cool!

    --pjm

    ReplyDelete
  5. I'm fairly sure this does not require a rooted or developer phone. I'll try to verify that though and maybe post something to clear up what looks like a lot of confusion about what it means to jailbreak an Android device.

    On reddit I also see comments about the usefulness of Python or Lua on Android. I haven't had a chance to explore it more than getting the interpreter running, but I doubt I'll stop there.

    ReplyDelete
  6. Thanks to people like you and your friends my dream of not having to use Java outside of my Ph.D. will be realized.

    ReplyDelete
  7. Nice work, man! Android just got a lot more attractive :)

    ReplyDelete
  8. That's cool. I bet G will release full Python support. Just because Python is better than Java (at least for programmers).

    ReplyDelete
  9. Anyone tried Jython?
    http://www.jython.org/docs/jythonc.html

    ReplyDelete
  10. Yes, the Jythonroid project is a port of Jython to Android.

    ReplyDelete
  11. Cheers! I've been following android development [im]patiently waiting for some move towards supporting python, ruby, and perl natively (like many developers out there, I *hate* java); while this isn't quite to the point of allowing python-based apps to be distributed to the non-techie public, at least it gives me incentive to buy an android phone (as soon as they release nicer hardware than the G1, that is)

    ReplyDelete
  12. Thanks. It said 'Apply the following patch to the Python source.'

    Can you please explain how to get and apply the patch?

    Thank you.

    ReplyDelete
  13. Hi,

    I tried to follow the instruction,but when i try ' make install prefix=./python-android HOSTPYTHON=./hostpython \'

    I get compile errors:

    make install prefix=./python-android HOSTPYTHON=./hostpython \
    > HOSTPGEN=./Parser/hostpgen BLDSHARED="agcc -shared" CROSS_COMPILE=yes
    agcc -c -DNDEBUG -g -O3 -Wall -Wstrict-prototypes -I. -I./Include -DPy_BUILD_CORE -o Modules/python.o Modules/python.c
    agcc -c -DNDEBUG -g -O3 -Wall -Wstrict-prototypes -I. -I./Include -DPy_BUILD_CORE -o Parser/acceler.o Parser/acceler.c
    agcc -c -DNDEBUG -g -O3 -Wall -Wstrict-prototypes -I. -I./Include -DPy_BUILD_CORE -o Parser/grammar1.o Parser/grammar1.c
    Parser/grammar1.c: In function 'char* PyGrammar_LabelRepr(label*)':
    Parser/grammar1.c:39: warning: deprecated conversion from string constant to 'char*'
    agcc -c -DNDEBUG -g -O3 -Wall -Wstrict-prototypes -I. -I./Include -DPy_BUILD_CORE -o Parser/listnode.o Parser/listnode.c
    agcc -c -DNDEBUG -g -O3 -Wall -Wstrict-prototypes -I. -I./Include -DPy_BUILD_CORE -o Parser/node.o Parser/node.c
    Parser/node.c: In function 'int PyNode_AddChild(node*, int, char*, int)':
    Parser/node.c:94: warning: comparison between signed and unsigned integer expressions
    agcc -c -DNDEBUG -g -O3 -Wall -Wstrict-prototypes -I. -I./Include -DPy_BUILD_CORE -o Parser/parser.o Parser/parser.c
    agcc -c -DNDEBUG -g -O3 -Wall -Wstrict-prototypes -I. -I./Include -DPy_BUILD_CORE -o Parser/parsetok.o Parser/parsetok.c
    agcc -c -DNDEBUG -g -O3 -Wall -Wstrict-prototypes -I. -I./Include -DPy_BUILD_CORE -o Parser/bitset.o Parser/bitset.c
    agcc -c -DNDEBUG -g -O3 -Wall -Wstrict-prototypes -I. -I./Include -DPy_BUILD_CORE -o Parser/metagrammar.o Parser/metagrammar.c
    Parser/metagrammar.c:120: warning: deprecated conversion from string constant to 'char*'
    Parser/metagrammar.c:120: warning: deprecated conversion from string constant to 'char*'
    Parser/metagrammar.c:120: warning: deprecated conversion from string constant to 'char*'
    Parser/metagrammar.c:120: warning: deprecated conversion from string constant to 'char*'
    Parser/metagrammar.c:120: warning: deprecated conversion from string constant to 'char*'
    Parser/metagrammar.c:120: warning: deprecated conversion from string constant to 'char*'
    Parser/metagrammar.c:120: warning: deprecated conversion from string constant to 'char*'
    Parser/metagrammar.c:120: warning: deprecated conversion from string constant to 'char*'
    Parser/metagrammar.c:120: warning: deprecated conversion from string constant to 'char*'
    Parser/metagrammar.c:120: warning: deprecated conversion from string constant to 'char*'
    Parser/metagrammar.c:120: warning: deprecated conversion from string constant to 'char*'
    Parser/metagrammar.c:120: warning: deprecated conversion from string constant to 'char*'
    Parser/metagrammar.c:141: warning: deprecated conversion from string constant to 'char*'
    agcc -c -DNDEBUG -g -O3 -Wall -Wstrict-prototypes -I. -I./Include -DPy_BUILD_CORE -o Parser/firstsets.o Parser/firstsets.c
    agcc -c -DNDEBUG -g -O3 -Wall -Wstrict-prototypes -I. -I./Include -DPy_BUILD_CORE -o Parser/grammar.o Parser/grammar.c
    Parser/grammar.c: In function 'void translabel(grammar*, label*)':
    Parser/grammar.c:197: error: invalid conversion from 'void*' to 'char*'
    make: *** [Parser/grammar.o] Error 1


    Can you please tell me what am I missing?

    Thank you.

    ReplyDelete
  14. This comment has been removed by the author.

    ReplyDelete
  15. I get the python source 2.4.5: http://www.python.org/download/releases/2.4.5/

    When i apply the first patch in the blog, i get the following error:

    patch -p1 < ../Python2.4.5_xcompile.patch
    patching file Makefile.pre.in
    Hunk #1 FAILED at 166.
    Hunk #2 FAILED at 193.
    Hunk #3 FAILED at 326.
    Hunk #4 FAILED at 457.
    Hunk #5 FAILED at 750.
    Hunk #6 FAILED at 858.
    6 out of 6 hunks FAILED -- saving rejects to file Makefile.pre.in.rej
    patching file Modules/pwdmodule.c
    Hunk #1 FAILED at 77.
    1 out of 1 hunk FAILED -- saving rejects to file Modules/pwdmodule.c.rej
    patching file Modules/socketmodule.c
    Reversed (or previously applied) patch detected! Assume -R? [n] n
    Apply anyway? [n] n
    Skipping patch.
    1 out of 1 hunk ignored -- saving rejects to file Modules/socketmodule.c.rej
    patching file Objects/fileobject.c
    Reversed (or previously applied) patch detected! Assume -R? [n] n
    Apply anyway? [n] n
    Skipping patch.
    1 out of 1 hunk ignored -- saving rejects to file Objects/fileobject.c.rej
    patching file Python/pystrtod.c
    Hunk #1 FAILED at 54.
    Hunk #2 FAILED at 218.
    2 out of 2 hunks FAILED -- saving rejects to file Python/pystrtod.c.rej
    patching file setup.py
    Reversed (or previously applied) patch detected! Assume -R? [n] n
    Apply anyway? [n] ^X^C
    [1]- Done emacs ../Python2.4.5_xcompile.patch
    [2]+ Done emacs Makefile.pre.in


    Can you please tell me how to solve my problem?

    Thank you.

    ReplyDelete
  16. @ying
    Well, unfortunately I've reproduced your issue. There's definitely something wrong with the patch. I'll work on it and post a fix. I'll probably post the actual binary also.

    ReplyDelete
  17. A binary would be fantastic :)

    ReplyDelete
  18. Binary posted. I'll update the build instructions later.

    ReplyDelete
  19. how do i get the binary to install on the G1? I'm pretty new to this in general, hope yall can help.

    ReplyDelete
  20. You'll need to use adb to push the binary to the phone. Then, using the adb shell, chmod it to be executable.

    ReplyDelete
  21. I got it pushed over and made into an executable, however i'm not sure what to do next. Its not a simple "# python2.4" :)

    ReplyDelete
  22. @TheMaxx Sorry for the delay in responding. I was busy working on my Android Scripting Environment project :) That should make it easier for you to experiment with Python on Android.

    ReplyDelete
  23. how can i make a .apk of a python app, with gui for android? i wish they made a python plugin to app inventor. --> http://code.google.com/p/app-inventor-for-android/issues/detail?id=993

    ReplyDelete