Cross compile Python for Android

前置作業 & 注意事項

  1. 產生要移植平台相對應的 standalone toolchain ,參考 Android API level (系統版本) 傳送門
  2. cross compile relative libs. link
  3. 修正 cross compile 與 auto conf 期間產生的錯誤
  4. 注意編譯需將 libs 都編譯成 static mode. (non-dynamic mode) 目的是可以方便使用,缺點是檔案大小會較大,不過動態連結,缺點是在入時會呼叫外部的 *.so 檔,Linux 底下的動態連函式庫(Dynamic link library)。(DLL) 但是手機的路徑與 Linux 預設路徑是不同的,所以使用 static mode 不外部呼叫 DLL 是最保險,不然還要去處理載入外部的路徑問題。
  5. 下載 Python source code,也可以使用 MEGA 載點的,已經修正錯誤。
  6. 如果使用自行下載的 source 編譯與 auto conf 發生錯誤,可以自行參考MEGA 載點中的 source 裡的檔案,看是如何修改的。

Python-2.7.1

  1. MEGA 載點或 Python 官網下載 source code
  2. 若從MEGA上下載,可以跳過這一點。這一點是上 patch ,MEGA 載點裡有這個檔案可以使用:python-2.7.1-cross-compile.patch
  3. 編譯 host 版本的 Python
  4. 把產生執行檔改成:
    mv python hostpython
    mv Parser/pgen Parser/hostpgen
  5. 按照下面的 android-configure bash script file

#上 patch,第 2 點

patch -p1 < /path/to/python-2.7.1-cross-compile.patch


#android-configure

#!/bin/bash

export TOOLCHAIN=/home/lab501/android-toolchain-16
export PATH=$TOOLCHAIN/bin:$PATH
export CC=$TOOLCHAIN/bin/arm-linux-androideabi-gcc
export CXX=$TOOLCHAIN/bin/arm-linux-androideabi-g++
export RANLIB=$TOOLCHAIN/bin/arm-linux-androideabi-ranlib
export AR=$TOOLCHAIN/bin/arm-linux-androideabi-ar
export LD=$TOOLCHAIN/bin/arm-linux-androideabi-ld
export STRIP=$TOOLCHAIN/bin/arm-linux-androideabi-strip
export ARCH="arm-linux-androideabi"
#export LD_LIBRARY_PATH="/data/local/tmp/_install_python/lib"
#change your shared libs'(libpython.so) path (LDFLAGS= --rpath)

./configure \
     LDFLAGS="-static -static-libgcc -fPIE -pie" \
    CFLAGS="-static -fPIE -pie" \
    --host=arm-linux-androideabi \
    --target=arm-linux-androideabi \
    --disable-shared \
    --prefix="/home/lab501/android-cross-compile-16/Python-2.7.1/_install"

make \
    HOSTPYTHON=/home/lab501/Python-2.7.1/hostpython \
    HOSTPGEN=/home/lab501/Python-2.7.1/Parser/hostpgen \
    CROSS_COMPILE=androideabi \
    CROSS_COMPILE_TARGET=yes \
    BLDSHARED="arm-linux-androideabi-gcc -shared" \

#make install...
#make -i install \
    #HOSTPYTHON=/home/lab501/Python-2.7.1/hostpython \
    #BLDSHARED="arm-linux-androideabi-gcc -shared" \
    #CROSS_COMPILE=androideabi \
    #CROSS_COMPILE_TARGET=yes

修改:setup.py 檔,設定如何 build modules

#for example, build hashlib modules
#只加入下面這兩行
#find_library_file(self.compiler, 'Modules',lib_dirs,
#       ['/home/lab501/Python-2.7.1/Modules'] )

if have_any_openssl:
#if have_usable_openssl:
# The _hashlib module wraps optimized implementations
# of hash functions from the OpenSSL library.
#comment this code. In order to cross compile hashlib.
#exts.append( Extension('_hashlib', ['_hashopenssl.c'],
# include_dirs = ssl_incs,
# library_dirs = ssl_libs,
# libraries = ['ssl', 'crypto']) )

#add this code. In order to cross compile hashlib. Important
find_library_file(self.compiler, 'Modules',lib_dirs,
['/home/lab501/Python-2.7.1/Modules'] )
#else:
# print ("warning: openssl 0x%08x is too old for _hashlib" %
# openssl_ver)
# missing.append('_hashlib')
#if COMPILED_WITH_PYDEBUG or not have_usable_openssl:
# The _sha module implements the SHA1 hash algorithm.
#comment this code. In order to cross compile hashlib.
#exts.append( Extension('_hashlib', ['shamodule.c']) )
# The _md5 module implements the RSA Data Security, Inc. MD5

參考資料

How-to-Cross-Compile-Python-and-Run-in-Embedded-System

howto-cross-compile-python-25

後記

build modules :要自己去調整 setup.py 要試試看,有可能會調整失敗,try and error.