http://wiki.woodpecker.org.cn/moin/Cross_Compile_Python_2.5.2_For_ARM
前言
本文主要參考 LeoJay 同學的 LeoJay/HOWTOCrossCompilePythonForARM
我也是剛接觸交叉編譯, 歡迎各位拍磚 -- border
編譯環境
ubuntu 8.04
gcc 4.2.3
arm_v5t_le-gcc
3.4.3
下載Python
http://www.python.org/download/ 下載Python源碼,我下載的::
http://www.python.org/ftp/python/2.5.2/Python-2.5.2.tar.bz2
解壓
tar jxvf Python-2.5.2.tar.bz2
cd Python-2.5.2
編譯pc版本的語法解析器
由於在編譯python的時候,需要先編譯一個叫pgen的程序出來, 用於生成語法解析器,所以我們要先生成一個pc版本的pgen::
border@b0rder:~/tools/Python-2.5.2$ mkdir build.pc
border@b0rder:~/tools/Python-2.5.2$ cd build.pc/
border@b0rder:~/tools/Python-2.5.2/build.pc$ ../configure
border@b0rder:~/tools/Python-2.5.2/build.pc$ 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
把這兩段以及中間的內容都刪除掉就可以 了, 我的是從 22496 - 22583 行,不同的版本可能不一樣。
編譯arm版本的python
有了語法解析器,就可以開始編譯arm版本的python了::
border@b0rder:~/tools/Python-2.5.2/build.pc$ mkdir ../build.arm
border@b0rder:~/tools/Python-2.5.2/build.pc$ cd ../build.arm/
border@b0rder:~/tools/Python-2.5.2/build.arm$ ../configure --prefix=/opt/arm-test/rootfs --disable-ipv6 --host=arm_v5t_le --enable-shared
先創建一個用於編譯的目錄 build.arm,再對python做一些配置,如安裝目錄,不要ipv6,使用arm_v5t_le的編譯器(你的可能是arm-linux),生成 動態鏈接庫。
修改Makefile
去掉Debug
OPT= -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes
一行中,去掉-g,我們不要 debug python,-O3改爲-O2,空間緊張O2就可以了。 我的是59行。
修改PGEN
PGEN= Parser/pgen$(EXE)
一行的下面加上
PGEN_HOST= ../build.pc/Parser/pgen$(EXE)
表明我們在HOST上運行的 pgen
在要使用PGEN的地方改爲PGEN_HOST (494行)::
$(GRAMMAR_H) $(GRAMMAR_C): $(PGEN) $(GRAMMAR_INPUT)
-@ mkdir Include
-$(PGEN) $(GRAMMAR_INPUT) $(GRAMMAR_H) $(GRAMMAR_C)
改爲::
$(GRAMMAR_H) $(GRAMMAR_C): $(PGEN) $(GRAMMAR_INPUT)
-@ mkdir Include
-$(PGEN_HOST) $(GRAMMAR_INPUT) $(GRAMMAR_H) $(GRAMMAR_C)
修改BUILDPYTHON
修改所有使用新生成的python的地方爲本機的python絕對地 址. 所有如 ./$(BUILDPYTHON) 的地方,都改爲python (爲本地的python地址,不要使用剛剛編譯生成的./python), 在vim裏面使用
:%s/.//$(BUILDPYTHON)///usr//bin//python/g
我的是替換了11處。 如::
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) /usr/bin/python -E -c 'import sys ; from distutils.util import get_platform ; print get_platform()+"-"+sys.version[0:3]' >platform
這種地方比較多,大家小心修改。
如果出這樣的錯, 說明替換的有問題::
case $MAKEFLAGS in /
*-s*) LD_LIBRARY_PATH=/home/border/tools/Python-2.5.2/build.arm: CC='arm_v5t_le-gcc' LDSHARED='arm_v5t_le-gcc -shared' OPT='-DNDEBUG -fwrapv -O2 -Wall -Wstrict-prototypes' ./python -E ../setup.py -q build;; /
*) LD_LIBRARY_PATH=/home/border/tools/Python-2.5.2/build.arm: CC='arm_v5t_le-gcc' LDSHARED='arm_v5t_le-gcc -shared' OPT='-DNDEBUG -fwrapv -O2 -Wall -Wstrict-prototypes' ./python -E ../setup.py build;; /
esac
/bin/sh: line 2: ./python:無法執行二進制文件
修改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, imageop, rgbimg, readline,
ssl, openssl, bdb, dbm, termios, nsl, ncurses, bz2, linuxaudiodev, ossaudiodev, tkinter
main函數
- setup函數調用的時 候,把要安裝的scripts那一部分去掉
之後就可以 make && make install了.
常見問題
PYTHONHOME
在ARM機上執行時如果遇到::
[email protected]:~# python2.5
Could not find platform dependent libraries <exec_prefix>
Consider setting $PYTHONHOME to <prefix>[:<exec_prefix>]
Python 2.5.2 (r252:60911, Jul 31 2008, 18:05:30)
[GCC 3.4.3 (MontaVista 3.4.3-25.0.30.0501131 2005-07-23)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>>
沒有配置PYTHONHOME
PYTHONPATH
PYTHONPATH
export PYTHONHOME=/usr/lib/python2.5
export PYTHONPATH=.:$PYTHONHOME:$PYTHONHOME/site-packages
export PATH=$PATH:$PYTHONHOME:$PYTHONPATH
如果出現'import site' failed錯誤,就是PYTHONPATH配置出錯。
附上我修改後的 Makefile 和 setup.py 供大家參考
感謝 LeoJay 不厭其煩的指導。
參考
-
http://wiki.woodpecker.org.cn/moin/LeoJay/HOWTOCrossCompilePythonForARM
-
http://groups.google.com/group/python-cn/browse_thread/thread/89f7de96b5ea72dc
-- EOF --