給arm板編譯移植python(一)

2020-10-28 11:00:59

背景:

  人生苦短,我用Python。arm板上可以跑python的話,我們就能輕鬆愉快的做很多事了。

說明:

  編譯Python的嵌入式版需要直譯器解析setup.py從而編譯Python的模組,因此需要先編譯出host的直譯器。(有點像Go語言)

  Python   : Python 3.7.6

編譯:

home下新建一個目錄python3.7,在python3.7下新建make.sh指令碼。

cd ~
mkdir python3.7
cd python3.7
nano make.sh

編譯的話用這個一鍵編譯指令碼就可以了,複製以下內容到make.sh,BUILD_HOST需要改成自己的交叉編譯器:

#!/bin/sh
BASE=`pwd`
BUILD_HOST=arm-himix200-linux


OUTPUT=${BASE}/install/

make_dirs() {
    cd ${BASE}
    mkdir  compressed  install  source -p
    sudo ls
}

tget () { #try wget
    filename=`basename $1`
    echo "Downloading [${filename}]..."
    if [ ! -f ${filename} ];then
        wget $1
    fi

    echo "[OK] Downloaded [${filename}] "
}


download_package () {
    cd ${BASE}/compressed
    #下載包
    tget https://www.python.org/ftp/python/3.7.6/Python-3.7.6.tgz
}

tar_package () {
    cd ${BASE}/compressed
    ls * > /tmp/list.txt
    for TAR in `cat /tmp/list.txt`
    do
        tar -xf $TAR -C  ../source
    done
    rm -rf /tmp/list.txt
}

make_host () {
    cd ${BASE}/source/Python*
    ./configure
    make && sudo make install
    sudo rm /usr/bin/python
    sudo ln -s /usr/local/bin/python3 /usr/bin/python
}
make_target () {
    cd ${BASE}/source/Python*
    echo `pwd`
    sudo make clean
    mkdir build-${BUILD_HOST} -p
    cd  build-${BUILD_HOST}
    mkdir ${BASE}/install/python -p
    ../configure CC=${BUILD_HOST}-gcc \
    CXX=${BUILD_HOST}-g++ \
    --host=${BUILD_HOST} \
    --build=x86_64-linux-gnu \
    --target=${BUILD_HOST} --disable-ipv6 \
    --prefix=${BASE}/install/python \
    --enable-optimizations \
    ac_cv_file__dev_ptmx=yes ac_cv_file__dev_ptc=yes
    make && make install
}
make_dirs
download_package
tar_package
#make_host #如果沒有的話,需要安裝
make_target

檢視下本機python是否為python3.7,如果不是需要去掉make_host註釋,編譯python3.7,儲存退出,執行make.sh。

./make.sh

注意:指令碼裡有些命令需要sudo許可權,執行過程需要輸入密碼,但不可以為了省事sudo ./make.sh,否則會導致檔案許可權問題使得交叉編譯器無法執行。

部署:

將編譯生成的python目錄放到目標板中,新增以下環境變數:

(假設 python 目錄放在 /mnt/nfs/python)

export PATH=$PATH:/mnt/nfs/python/bin   # 用於執行python,填寫 Python目錄中的Bin目錄即可
export PYTHONPATH=               # 這一行是為了額外的模組的搜尋,根據實際模組的使用情況進行填寫,可留空,可參考附錄進行填寫
export PYTHONHOME=/mnt/nfs/python      # 最終的安裝路徑,必須填寫
  • 環境變數可以寫入/etc/profile檔案末尾,執行source /etc/profile以啟用。

(如果不新增,會導致;關於這裡可以參考:根據:https://askubuntu.com/questions/905372/could-not-find-platform-independent-libraries-prefix)

Fatal Python error: initfsencoding: unable to load the file system codecModuleNotFoundError: No module named 'encodings'Current thread 0xb6f28000 (most recent call first):Aborted有關的解釋是這樣的:
  •  

必須設定2個環境變數 PYTHONPATH 與 PYTHONHOME.因為python3直譯器搜尋有關庫時依賴這2個變數:

PYTHONPATH 作為 模組 的預設搜尋路徑 (The PYTHONPATH variable augments the default search path for module files.)

PYTHONHOME 用於 python標準庫(PYTHONHOME is used for standard python libraries. ),

設定變數的格式以shell格式即可,例如我設定的環境變數如下:

export PATH=$PATH:/mnt/python/python3.7/bin
export PYTHONPATH='/mnt/python/python3.7:/mnt/python/python3.7/lib:/mnt/python/python3.7/lib/python3.7/site-packages'
export PYTHONHOME=/mnt/python/python3.7

現在可以在板子終端裡敲入python按tab可以自動補全為python3的話,說明環境變數設定成功,執行python3進入repl,如下圖已經可以正常執行python了。

      但是還有些基礎module沒有移植進來,後面的話很多module都會依賴到,可以在repl中輸入help('modules')檢視目前已有的modules,目前缺少zlib,_ctypes,_ssl等模組,這些都是後面實現pip所必須的。其中_ctypes為setuptools依賴模組,有了setuptools我們也可以在板子上下載第三方模組手動安裝,在python3.7之前的版本_ctypes是可以隨著編譯python一起編好的,不需要額外移植。

後面的文章將繼續講如何移植這些必要模組