[轉] 移植Python 到S3C2440

出處:http://tc.itkee.com/developer/detail-220e.html

移植環境:
HOST: Fedora 12
交叉編譯器:Sourcery G++ Lite 2009q3-67 for ARM GNU/Linux
交叉編譯程序:Sqlite 3.6.23.1,Python 2.6.5
下載源碼:
Sqlite 3.6.23.1 http://www.sqlite.org/sqlite-3.6.23.1.tar.gz
Python 2.6.5 http://www.python.org/ftp/python/2.6.5/Python-2.6.5.tar.bz2由於sqlite是python的標準組件所以我們要先進行sqlite的移植。
交叉編譯sqlite:
配置編譯選擇:
1
2
3
4
5
tar xvf sqlite-3.6.23.1.tar.gz
mkdir sqlite-build
cd sqlite-3.6.23.1
./configure --host=arm-linux --prefix=/home/lzz/working/apps/sqlite-build --enable-shared
--disable-readline --disable-dynamic-extensions
以上的命令我們先解壓了源碼,然後進入源碼目錄執行configure來配置編譯選項, 各個參數的意思是:–host=arm-linux 說明我們要編譯arm版本的sqlite;–prefix=/home/lzz/working/apps/sqlite-build 說明我們要把編譯好的sqlite安裝到sqlite-build目錄;–enable-shared 生成動態鏈接庫;–disable-readline 禁用sqlite的readline;–disable-dynamic-extensions 禁用sqlite的動態擴展。
編譯和安裝:
1
2
Make
Make install
這兩個命令就不用解釋了吧。執行完這兩個命令後就可以在sqlite-build目錄下看到三個目錄分別是bin,include和lib目錄,把bin目錄下的sqlite3拷到文件系統的bin目錄下,把lib目錄下的內容拷到文件系統的lib目錄下就ok了(注意:如果出現sqlite不能在開發板上運行的情況,很可能是由於缺少相應的庫文件導致的,你只需要按照錯誤提示在你的交叉編譯環境中找到相應的庫文件拷到文件系統的lib目錄下即可)。下圖是在我的tq2440上運行的效果交叉編譯Python:
解壓Python
1
2
tar xvf Python-2.6.5.tar.bz2
mkdir python-build
編譯PC版的Python:
1
2
3
4
5
cd Python-2.6.5
mkdir python-pc
cd python-pc
../configure
make
有人可能會問,我們爲什麼要編譯pc版的python。其實原因是這樣的,在python編譯過程中,第一階段會產生一個python的可執行版本,然後會進入第二階段去按照setup.py來定義去編譯附加的python模塊。而在處理setup.py時其實就需要用到python解析器了,但是我們如果是在編譯嵌入式版本的話,那麼第一階段產生的python可執行程序是arm版本的,它不能運行在我們的pc機上所以不能用它來處理setup.py。所以我們要提前編譯一個pc 上的python來處理setup.py。
這時在當前的python-pc目錄下就會出現python解釋器了。
修改configure文件:
由於configure文件在檢測編譯器的printf是否支持%zd的時候如果發現是在cross compile就會退出,所以我們要先去掉這段檢測代碼用vim打開configure文件查找%zd printf()就會發現如下代碼:
1
2
3
4
{ 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
{ { echo "$as_me:$LINENO: error: cannot run test program while cross compiling
然後往下找,一直找到這裏
1
2
3
4
5
6
( exit $ac_status )
{ echo "$as_me:$LINENO: result: no" >&5
echo "${ECHO_T}no" >&6; }
fi
rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
fi
刪掉或註釋掉這兩段以及中間的部分就可以了。
編譯arm版本的python:
1
2
3
4
mkdir python-arm
cd python-arm
../configure --host=arm-linux --prefix=/home/lzz/working/apps/python-build
--disable-ipv6 --enable-shared
上面的編譯選項的意思和sqlite的相同就不再解釋了。
然後我們修改生成的Makefile文件去掉調試信息,方法是在Makefile文件中查找OTP找到 OPT= -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes 這一行把-g選項去掉,如果空間緊張的話,還可以把-O3改成-O2。
繼續查找PGEN,在PGEN = Parser/pgen$(EXE)一行的下面添加PGEN_HOST= ../build-pc/Parser/pgen$(EXE)
在要使用PGEN進行解釋的地方使用PGEN_HOST大約在Makefile文件的540
1
2
3
$(GRAMMAR_H) $(GRAMMAR_C): $(PGEN) $(GRAMMAR_INPUT)
-@$(INSTALL) -d Include
-$(PGEN) $(GRAMMAR_INPUT) $(GRAMMAR_H)   $(GRAMMAR_C)
改爲
1
2
3
$(GRAMMAR_H) $(GRAMMAR_C): $(PGEN) $(GRAMMAR_INPUT)
-@$(INSTALL) -d Include
-$(PGEN_HOST) $(GRAMMAR_INPUT) $(GRAMMAR_H)   $(GRAMMAR_C)
修改所有使用新生成的arm版的python的地方,把所有./$(BUILDPYTHON)的地方都改成../build-pc/python$(EXE),這樣的地方比較多,大家可以用在vim在打:號然後輸入%s/./$(BUILDPYTHON)/../build-pc/python$(EXE)/g命令來替換。
修改setup.py文件:
setup.py負責編譯python的各個擴展模塊。但是,由於python完全沒有考慮cross compile,所以要做一些修改。
我們需要修改 PyBuildExt類中的幾個部分
build_extension函數:
這個函數在編譯了所有的extension後,會去load這些剛編譯好的extension, 但我們在i686的電腦上顯然不能load,所以要跳過這些操作。 大概在238行在 build_ext.build_extension(self, ext)後面直接寫一個return,不做load。
去掉無用的搜索目錄:
函數的前兩行是把/usr/local加到搜索目錄中,我們的cross compiler一般不會直接安裝在 /usr/local裏面的,所以這兩行去掉(大概在314行):
1
2
add_dir_to_list(self.compiler.library_dirs, '/usr/local/lib')
add_dir_to_list(self.compiler.include_dirs, '/usr/local/include')
去掉不被支持的模塊
由於python本身的問題,現在ctypes還不能在除i386以外的機器上運行,所以去掉 ctypes。大概在1275行,把它註釋掉就可以了
1
self.detect_ctypes(inc_dirs, lib_dirs)
還可以根據自己的需要去掉不用的模塊,方法是在detect_modules函數中註釋掉相應的項,比如我要去掉cmath模塊
1
2
# complex math library functions
exts.append( Extension('cmath', ['cmathmodule.c'],libraries=math_libs) )
就可以把上面幾行註釋掉就可以了。
修改sqlite的編譯選項
我們要把setup.Py文件中對sqlite的引用路徑改成我們安裝sqlie的目錄,大概在910行,我們把
1
for d in inc_dirs + sqlite_inc_paths:
改成
1
for d in ['/home/lzz/working/apps/sqlite-build/include']:
修改main函數
最後我們把main函數中的scripts那一部分改成空,大大概在1913行把
1
2
3
scripts = ['Tools/scripts/pydoc', 'Tools/scripts/idle',
'Tools/scripts/2to3',
'Lib/smtpd.py']
改成
scripts=[]
編譯安裝python:
最後
1
2
make
make install
就可以了,編譯完成後我們會在python-build目錄下發現四個目錄,我們只要bin和lib目錄中的內容。我們把bin目錄中的文件拷到我們的文件系統的/usr/bin目錄,然後把lib目錄中的文件拷到文件系統的/usr/lib目錄中就ok了。注意:如果出現python不能運行的情況很可能是缺少相應的庫,你需要到你的交叉編譯環境中去拷相應的庫文件。
如果出現下面的錯誤提示就是你沒有設置python的環境變量
1
2
Could not find platform dependent libraries <exec_prefix>                      
Consider setting $PYTHONHOME to <prefix>[:<exec_prefix>]
這時你需要設置PYTHONHOME,如果出現下面的錯誤
‘import site faild’
這時你需要設置PYTHONPATH 。
最好是在你的文件系統的etc目錄下的profile文件中加入下面的語句
1
2
3
export PYTHONHOME=/usr/lib/python2.6
export PYTHONPATH=.:$PYTHONHOME:$PYTHONHOME/site-packages
export PATH=$PATH:$PYTHONHOME:$PYTHONPATH
這樣就不會出現上面的錯誤了。
裁減python:
我們發現我們編譯出來的python的庫文件有57M,如果你空間緊張可以刪除庫文件中擴展名爲py和pyc的文件,只留下pyo的文件。不過這樣做之後我們運行python就要加上-OO的參數如下圖就是帶-OO選項的運行情況參考文章:
http://wiki.woodpecker.org.cn/moin/LeoJay/HOWTOCrossCompilePythonForARM
http://ifis.blog.hexun.com/44254479_d.html
未經允許不得轉載:GoMCU » [轉] 移植Python 到S3C2440