來源:http://hi.baidu.com/vaico/blog/item/2d39d0c497b54da18326ac7d.html
我需要在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
先去 http://www.sqlite.org/download.html 下載最新的sqlite源代碼,我這裏用的是3.5.6版本的。
我推薦使用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 <<\_ACEOF #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 's/^/| /' 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
有了語法解析器,就可以開始編譯arm版本的python了。
mkdir ../build.arm cd ../build.arm ../configure --prefix=/home/leojay/test/arm-system-working/rootfs --disable-ipv6 --host=arm-linux --enable-shared
先創建一個用於編譯的目錄build.arm,再對python做一些配置,如安裝目錄,不要ipv6,使用arm-linux的編譯器,生成動態鏈接庫。
修改Makefile
之後就要對Makefile做一些修改,把
OPT= -DNDEBUG -g -O3 -Wall -Wstrict-prototypes
一行中,去掉-g,我們不要debug python,-O3改爲-O2,空間緊張O2就可以了。
在
PGEN= Parser/pgen$(EXE)
一行的下面加上
PGEN_HOST= ../build.pc/Parser/pgen$(EXE)
表明我們在HOST上運行的pgen
在要使用PGEN的地方改爲PGEN_HOST:
$(GRAMMAR_H) $(GRAMMAR_C): $(PGEN) $(GRAMMAR_INPUT) -$(PGEN) $(GRAMMAR_INPUT) $(GRAMMAR_H) $(GRAMMAR_C)
改爲:
$(GRAMMAR_H) $(GRAMMAR_C): $(PGEN) $(GRAMMAR_INPUT) -$(PGEN_HOST) $(GRAMMAR_INPUT) $(GRAMMAR_H) $(GRAMMAR_C)
修改所有使用新生成的python的地方。
所有如 ./$(BUILDPYTHON) 的地方,都改爲python
如:
platform: $(BUILDPYTHON) $(RUNSHARED) ./$(BUILDPYTHON) -E -c 'import sys ; from distutils.util import get_platform ; print get_platform()+"-"+sys.version[0:3]' >platform
改爲
platform: $(BUILDPYTHON) $(RUNSHARED) python -E -c 'import sys ; from distutils.util import get_platform ; print get_platform()+"-"+sys.version[0:3]' >platform
這種地方比較多,大家小心修改。
修改setup.py
setup.py負責編譯python的各個擴展模塊。但是,由於python完全沒有考慮cross compile,所以要做一些修改。
-
- build_extension函數:
- 這個函數在編譯了所有的extension後,會去 load這些剛編譯好的extension, 但我們在i686的電腦上顯然不能load,所以要跳過這些操作。 在 build_ext.build_extension(self, ext)後面直接寫一個return,不做load。
- detect_modules函數:
- 函數的前兩行是把/usr/local加到搜索目錄中,我們的cross compiler一般不會直接安裝在 /usr/local裏面的,所以這兩行去掉:
add_dir_to_list(self.compiler.library_dirs, '/usr/local/lib') add_dir_to_list(self.compiler.include_dirs, '/usr/local/include')
lib_dirs, inc_dirs的設定中,把中括號裏的那些都去掉。 以下所有模塊都不要: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本身的問題,現在ctypes還不能在除i386以外的機器上運行,所以ctypes也去掉 編譯sqlite的地方:for d in inc_dirs + sqlite_inc_paths:
改爲:for d in ['/usr/local/arm/3.3.2/include']:
因爲我的sqlite3安裝在這裏,如果這裏不改的話,setup.py會在我的電腦上找sqlite
- 函數的前兩行是把/usr/local加到搜索目錄中,我們的cross compiler一般不會直接安裝在 /usr/local裏面的,所以這兩行去掉:
- build_extension函數:
- main函數:
- setup函數調用的時候,把要安裝的scripts那一部分去掉
之後就可以make && make install了。
附上我修改後的 Makefile 和 setup.py 供大家參考
裁減python
python完全安裝後,實在是很大,所以,要把一些肯定用不上的庫去掉。 所以,再附上我的裁減腳本 cleanpy.sh
注意,由於我的python程序都運行在python -OO的參數下,所有的.py和.pyc都不需要, 只要有.pyo就可以了。所以,這個腳本會把所有的.py和.pyc都刪除掉。
大家可以根據自己的需要做調整。