안드로이드용 파이썬 제작하기
-----------------------------
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 ---- |