我需要在Arm9的s3c2440 CPU上运行python,以下是我的编译过程。
host编译环境:
ubuntu 7.04, gcc 4.2.1, arm-linux-gcc 3.3.2
要cross compile的程序:
sqlite 3.5.6,
python 2.5.1
编译sqlite
我推荐使用amalgamation版本的源代码,这个代码只有几个文件而已,编译起来方便,而且据说 编译器好的话,还可能编译出更高效的代码。 我下载的是
http://www.sqlite.org/sqlite-amalgamation-3.5.6.tar.gz
先运行以下几步:
tar zxf sqlite-amalgamation-3.5.6.tar.gz
cd sqlite-3.5.6
./configure --host=arm-linux --prefix=/usr/local/arm/3.3.2 --enable-shared --disable-readline --disable-dynamic-extensions
以上是把sqlite解压缩,然后做一些配置,这里,我希望sqlite到时候安装到/usr/local/arm/3.3.2里,要生成动态链接库,不要readline,不要sqlite的动态扩展。
然后编辑Makefile,把CFLAG和CXXFLAG中的-g去掉,我们不用debug sqlite。
接下来就可以编译和安装sqlite了:
make
make install
这一步就完成了sqlite的编译和安装了。
编译python
先去http://www.python.org/download/下载最新版本的python源代码,我这里下载的是:
http://www.python.org/ftp/python/2.5.1/Python-2.5.1.tar.bz2
先把python解压缩:
tar jxf Python-2.5.1.tar.bz2
cd Python-2.5.1
编译pc版本的语法解析器
由于在编译python的时候,需要先编译一个叫pgen的程序出来,用于生成语法解析器,所以我们要先生成一个pc版本的pgen:
mkdir build.pc
cd build.pc
../configure
make Parser/pgen
然后ls Parser一下,应该就能看到有pgen了。
修改configure
configure在检测编译器的printf是否支持%zd的时候,如果发现是在cross compile,就直接不干活了。这还了得?
把这一部分的检测代码去掉。这段代码起始于
echo "$as_me:$LINENO: checking for %zd printf() format support" >&5
echo $ECHO_N "checking for %zd printf() format support... $ECHO_C" >&6
if test "$cross_compiling" = yes; then
结束于
cat >>confdefs.h <
#define PY_FORMAT_SIZE_T "z"
_ACEOF
else
echo "$as_me: program exited with status $ac_status" >&5
echo "$as_me: failed program was:" >&5
sed &#39;s/^/| /&#39; conftest.$ac_ext >&5
( exit $ac_status )
echo "$as_me:$LINENO: result: no" >&5
echo "${ECHO_T}no" >&6
fi
rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
fi
把这两段以及中间的内容都删除掉就可以了。
编译arm版本的python
有了语法解析器&#xff0c;就可以开始编译arm版本的python了。
mkdir ../build.arm
cd ../build.arm
../configure --prefix&#61;/home/leojay/test/arm-system-working/rootfs --disable-ipv6 --host&#61;arm-linux --enable-shared
先创建一个用于编译的目录build.arm&#xff0c;再对python做一些配置&#xff0c;如安装目录&#xff0c;不要ipv6&#xff0c;使用arm-linux的编译器&#xff0c;生成动态链接库。
修改Makefile
之后就要对Makefile做一些修改&#xff0c;把
OPT&#61; -DNDEBUG -g -O3 -Wall -Wstrict-prototypes
一行中&#xff0c;去掉-g&#xff0c;我们不要debug python&#xff0c;-O3改为-O2&#xff0c;空间紧张O2就可以了。
在
PGEN&#61; Parser/pgen$(EXE)
一行的下面加上
PGEN_HOST&#61; ../build.pc/Parser/pgen$(EXE)
表明我们在HOST上运行的pgen
在要使用PGEN的地方改为PGEN_HOST:
$(GRAMMAR_H) $(GRAMMAR_C): $(PGEN) $(GRAMMAR_INPUT)
-$(PGEN) $(GRAMMAR_INPUT) $(GRAMMAR_H) $(GRAMMAR_C)
改为&#xff1a;
$(GRAMMAR_H) $(GRAMMAR_C): $(PGEN) $(GRAMMAR_INPUT)
-$(PGEN_HOST) $(GRAMMAR_INPUT) $(GRAMMAR_H) $(GRAMMAR_C)
修改所有使用新生成的python的地方。
所有如 ./$(BUILDPYTHON) 的地方&#xff0c;都改为python
如&#xff1a;
platform: $(BUILDPYTHON)
$(RUNSHARED) ./$(BUILDPYTHON) -E -c &#39;import sys ; from distutils.util import get_platform ; print get_platform()&#43;"-"&#43;sys.version[0:3]&#39; >platform
改为
platform: $(BUILDPYTHON)
$(RUNSHARED) python -E -c &#39;import sys ; from distutils.util import get_platform ; print get_platform()&#43;"-"&#43;sys.version[0:3]&#39; >platform
这种地方比较多&#xff0c;大家小心修改。
修改setup.py
setup.py负责编译python的各个扩展模块。但是&#xff0c;由于python完全没有考虑cross compile&#xff0c;所以要做一些修改。
build_extension函数&#xff1a;
这个函数在编译了所有的extension后&#xff0c;会去 load这些刚编译好的extension&#xff0c; 但我们在i686的电脑上显然不能load&#xff0c;所以要跳过这些操作。 在 build_ext.build_extension(self, ext)后面直接写一个return&#xff0c;不做load。
detect_modules函数&#xff1a;
函数的前两行是把/usr/local加到搜索目录中&#xff0c;我们的cross compiler一般不会直接安装在 /usr/local里面的&#xff0c;所以这两行去掉&#xff1a;
add_dir_to_list(self.compiler.library_dirs, &#39;/usr/local/lib&#39;)
add_dir_to_list(self.compiler.include_dirs, &#39;/usr/local/include&#39;)
lib_dirs, inc_dirs的设定中&#xff0c;把中括号里的那些都去掉。 以下所有模块都不要&#xff1a;
cmath, ctypes, _testcapi, pwd, grp, spwd, mmap, audioop, p_w_picpathop, rgbimg, readline,
ssl, openssl, bdb, dbm, termios, nsl, ncurses, bz2, linuxaudiodev, ossaudiodev, tkinter
由于python本身的问题&#xff0c;现在ctypes还不能在除i386以外的机器上运行&#xff0c;所以ctypes也去掉 编译sqlite的地方&#xff1a;
for d in inc_dirs &#43; sqlite_inc_paths:
改为&#xff1a;
for d in [&#39;/usr/local/arm/3.3.2/include&#39;]:
因为我的sqlite3安装在这里&#xff0c;如果这里不改的话&#xff0c;setup.py会在我的电脑上找sqlite
main函数&#xff1a;
setup函数调用的时候&#xff0c;把要安装的scripts那一部分去掉
之后就可以make && make install了。
裁减python
python完全安装后&#xff0c;实在是很大&#xff0c;所以&#xff0c;要把一些肯定用不上的库去掉。 所以&#xff0c;再附上我的裁减脚本 cleanpy.sh
注意&#xff0c;由于我的python程序都运行在python -OO的参数下&#xff0c;所有的.py和.pyc都不需要&#xff0c; 只要有.pyo就可以了。所以&#xff0c;这个脚本会把所有的.py和.pyc都删除掉。
大家可以根据自己的需要做调整。