天天看點

移植Python2.7到ARM-LINUX嵌入式平台

筆者長期在ARM-LINUX嵌入式平台使用C語言開發。硬體IO操作隻能用C确實沒辦法,但是應用程式用C簡直就苦了個逼了,程式複雜一點,各種越界、指針錯誤、詭異當機、segment fault、記憶體洩漏、core dump、編譯找不到頭檔案、依賴庫,解析個字元費老勁,輪子太少純靠白手起家。自從把Python移植到嵌入式平台,用C寫完IO的Python擴充庫然後用Python寫應用程式完全就是摧枯拉朽般存在。

  • Python版本:2.7.3
  • 交叉編譯器:arm-none-linux-gnueabi-
  • 硬體平台:AT91 ARM9、NUC97x、TI AM335x

源碼下載下傳&解壓

wget https://www.python.org/ftp/python/2.7.3/Python-2.7.3.tar.xz
xz -d Python-2.7.3.tar.xz
tar xvf Python-2.7.3.tar
           

編譯HOST版解釋器

編譯Python的嵌入式版需要解釋器解析setup.py進而編譯Python的子產品,是以需要先編譯出HOST的解釋器。

./configure
make python Parser/pgen
mv  python  hostpython
mv  Parser/pgen  Parser/hostpgen
make distclean
           

打交叉編譯更新檔

點選下載下傳更新檔

patch -p1 < Python-2.7.3-xcompile.patch
           

交叉編譯配置

設定交叉編譯工具鍊為arm-none-linux-gnueabi,編譯生成的執行檔案存放目錄為目前目錄的_install檔案夾。

./configure --host=arm-none-linux-gnueabi --prefix=$PWD/_install
           

編譯&安裝

make HOSTPYTHON=./hostpython HOSTPGEN=./Parser/hostpgen BLDSHARED="arm-none-linux-gnueabi-gcc -shared" CROSS_COMPILE=arm-none-linux-gnueabi- CROSS_COMPILE_TARGET=yes
make install HOSTPYTHON=./hostpython BLDSHARED="arm-none-linux-gnueabi-gcc-shared" CROSS_COMPILE=arm-none-linux-gnueabi- CROSS_COMPILE_TARGET=yes prefix=$PWD/_install
           

執行完以上指令之後在_install中産生bin lib include share 4個檔案夾,避免麻煩可以将以上指令寫成一個腳本。

目标闆檔案拷貝

将_install/bin 中的所有内容拷貝到目标闆的任意環境變量能夠通路到的目錄即可,推薦/bin、/usr/bin。

将_install/lib 中的所有内容拷貝到目标闆/lib中

将_install /include 中的所有内容拷貝到目标闆/include中。因為其中的某些頭檔案是Python環境所需要的,比如Python解釋器啟動依賴于pyconfig.h,import time子產品時依賴timefuncs.h。

環境變量設定

将python2.7路徑加入到環境變量 PYTHONHOME、PYTHONPATH中。

如果是/etc/profile,在檔案末尾添加如下資訊然後執行 source /etc/profile。

export PYTHONPATH=/lib/python2.7:$PYTHONPATH
export PYTHONHOME=/lib/python2.7:$PYTHONHOME
           

如果是指令行,執行如下:

export PYTHONPATH=$PYTHONPATH:/lib/python2.7
export PYTHONHOME=$PYTHONHOME:/lib/python2.7
           

驗證目标闆Python

打開解釋器,import 一些常用子產品,編寫程式測試。

後記

可能import time、datetime、threading、multiprocessing時提示缺少time、_collections、itertools等子產品。

這些是 builtin 子產品,可以通過sys.builtin_module_names檢視。其源碼在Modules目錄中,編譯完成以 .so 的形式存放在/lib/python2.7/lib-dynload中。

首先在setup.py中 disabled_module_list=[] 是否将這些子產品disabled掉了。

如果依然無法解決,則在Modules/config.c中參考其他子產品的寫法添加代碼,手動編譯即可在build/lib.xx.2.7目錄中産生 .so 檔案。