筆者長期在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 檔案。