將Python3移植到android9.0平臺(交叉編譯)


注:因此python需要交叉編譯,使用系統自帶python3執行命令的過程中,可能會出現找不到函數的去情況:
交叉編譯Python的時候最好保證電腦上的Python版本和要編譯的Python版本一致,即先編譯安裝Linux版本,再編譯arm版本。

1. 源碼下載

從https://www.python.org/下載源碼。
我這裏下載最新的 Python3.7.4。

2. Linux(服務器)版本的Python3.7.4 編譯並安裝:

Linux(服務器)版本的Python3.7.4 安裝

3. 編譯安卓版本

3.1 下載NDK

https://developer.android.google.cn/ndk/downloads/
我這裏選擇的是Linux 64 位 (x86) android-ndk-r20-linux-x86_64.zip版本

3.2 解壓Python-3.7.4.tgz

使用編譯,編譯腳本放在Python-3.7.4的根目錄。
編譯腳本如下:

#!/bin/bash
COMPILE_ROOT=`pwd`
ANDROID_NDK_ROOT=/home/xxt/ndk/android-ndk-r20
ANDROID_GCC_ROOT=${ANDROID_NDK_ROOT}/toolchains/llvm/prebuilt/linux-x86_64
ANDROID_GCC_PATH=${ANDROID_GCC_ROOT}/bin

BUILD_PATH=${COMPILE_ROOT}/build
OUT_PATH=${COMPILE_ROOT}/out

OPENSSL_PATH=${COMPILE_ROOT}/thirdparty/libressl-2.7.4/out
OPENSSL_LIB_PATH=${COMPILE_ROOT}/thirdparty/libressl-2.7.4/out/lib

CROSS_COMPILER=aarch64-linux-android-
CROSS_COMPILER_CLANG=aarch64-linux-android28-

#prepare
mkdir -p ${BUILD_PATH}
mkdir -p ${OUT_PATH}
export PATH=${ANDROID_NDK_ROOT}:${ANDROID_GCC_PATH}:$PATH

export ARCH="aarch64"
export CC="${CROSS_COMPILER_CLANG}clang -pie -fPIE" 
export CPP="${CROSS_COMPILER_CLANG}clang -E  -pie -fPIE"
export CXX="${CROSS_COMPILER_CLANG}clang++  -pie -fPIE"

export AS="${CROSS_COMPILER}as"
export LD="${CROSS_COMPILER}ld  -pie -fPIE"
export GDB="${CROSS_COMPILER}gdb"
export STRIP="${CROSS_COMPILER}strip"
export RANLIB="${CROSS_COMPILER}ranlib"
export OBJCOPY="${CROSS_COMPILER}objcopy"
export OBJDUMP="${CROSS_COMPILER}objdump"
export AR="${CROSS_COMPILER}ar"
export NM="${CROSS_COMPILER}nm"
export READELF="${CROSS_COMPILER}readelf"
export M4=m4
export TARGET_PREFIX=$CROSS_COMPILER
export CONFIG_SITE="config.site"
export CXXFLAGS="-D__ANDROID_API__=28 "

cd ${BUILD_PATH}

echo -e "ac_cv_file__dev_ptmx=yes\nac_cv_file__dev_ptc=no" > config.site

../configure --host=aarch64-linux-android  \
--host=aarch64-linux \
--build=x86_64-pc-linux-gnu \
--target=aarch64-linux-android \
LDFLAGS="-Wl,--allow-shlib-undefined -D__ANDROID_API__=28 -fPIC -L${OPENSSL_LIB_PATH}" \
CFLAGS="-D__ANDROID_API__=28  " \
CPPFLAGS="-D__ANDROID_API__=28" \
--enable-shared \
--enable-ipv6 \
--with-openssl=${OPENSSL_PATH} \
--prefix=${OUT_PATH}

make -j8 2>&1 |tee build.log
echo "-----------build success!-------------"

make install
echo "-----------install success!-------------"

這中間使用了交叉編譯的libressl-2.7.4
編譯腳本跟上面的類似。

編譯完成後,仍然有模塊沒有編譯:

Python build finished successfully!
The necessary bits to build these optional modules were not found:
_bz2                  _curses               _curses_panel
_dbm                  _gdbm                 _lzma
_sqlite3              _tkinter              nis
readline              spwd                  zlib
To find the necessary bits, look in setup.py in detect_modules() for the module's name.


The following modules found by detect_modules() in setup.py, have been
built by the Makefile instead, as configured by the Setup files:
_abc                  atexit                pwd
time


Failed to build these modules:
_crypt                _ctypes               _uuid

先不管,看下在板子上能夠運行。

out目錄下已經生成了需要的庫和bin文件:

$ ls out/
bin  include  lib  share

4. 板端測試:

python out/bin路徑下的所有文件複製到/vendor/bin
python out/lib路徑下的libpython3.7m.so.1.0、 libpython3.so文件複製到/vendor/lib64
python out/lib路徑下的文件夾python3.7複製到/vendor/lib
libressl-2.7.4 out/lib路徑下的libssl.so.45、libcrypto.so.43文件複製到/vendor/lib64
跑Python3

#  python3
]Python 3.7.4 (default, Aug  8 2019, 15:24:32)
[Clang 8.0.7 (https://android.googlesource.com/toolchain/clang b55f2d4ebfd35bf6 on linux
Type "help", "copyright", "credits" or "license" for more information.
>>>

測試程序 helloworld.py

print('hello world !')

打印:

 # python3 helloworld.py
hello world !

移植成功。

5. 編譯進vendor.img

編譯好的out文件放到了product下的xx產品的目錄下,使用下面的mk拷貝。
python-packages.mk

PRODUCT_COPY_FILES += $(call add-to-product-copy-files-if-exists,\
			$(LOCAL_PATH)/python3.7/lib/libpython3.7m.so.1.0:$(TARGET_COPY_OUT_VENDOR)/lib64/libpython3.7m.so.1.0 \
			$(LOCAL_PATH)/python3.7/lib/libpython3.so:$(TARGET_COPY_OUT_VENDOR)/lib64/libpython3.so \
			$(LOCAL_PATH)/python3.7/libressl/libssl.so.45:$(TARGET_COPY_OUT_VENDOR)/lib64/libssl.so.45 \
			$(LOCAL_PATH)/python3.7/libressl/libcrypto.so.43:$(TARGET_COPY_OUT_VENDOR)/lib64/libcrypto.so.43 )
			
PRODUCT_COPY_FILES += $(call add-to-product-copy-files-if-exists,\
					$(LOCAL_PATH)/python3.7/bin/2to3:$(TARGET_COPY_OUT_VENDOR)/bin/2to3 \
					$(LOCAL_PATH)/python3.7/bin/2to3-3.7:$(TARGET_COPY_OUT_VENDOR)/bin/2to3-3.7 \
					$(LOCAL_PATH)/python3.7/bin/idle3:$(TARGET_COPY_OUT_VENDOR)/bin/idle3 \
					$(LOCAL_PATH)/python3.7/bin/idle3.7:$(TARGET_COPY_OUT_VENDOR)/bin/idle3.7 \
					$(LOCAL_PATH)/python3.7/bin/pydoc3:$(TARGET_COPY_OUT_VENDOR)/bin/pydoc3 \
					$(LOCAL_PATH)/python3.7/bin/pydoc3.7:$(TARGET_COPY_OUT_VENDOR)/bin/pydoc3.7 \
					$(LOCAL_PATH)/python3.7/bin/python3:$(TARGET_COPY_OUT_VENDOR)/bin/python3 \
					$(LOCAL_PATH)/python3.7/bin/python3.7:$(TARGET_COPY_OUT_VENDOR)/bin/python3.7 \
					$(LOCAL_PATH)/python3.7/bin/python3.7-config:$(TARGET_COPY_OUT_VENDOR)/bin/python3.7-config \
					$(LOCAL_PATH)/python3.7/bin/python3.7m:$(TARGET_COPY_OUT_VENDOR)/bin/python3.7m \
					$(LOCAL_PATH)/python3.7/bin/python3.7m-config:$(TARGET_COPY_OUT_VENDOR)/bin/python3.7m-config \
					$(LOCAL_PATH)/python3.7/bin/pyvenv:$(TARGET_COPY_OUT_VENDOR)/bin/pyvenv \
					$(LOCAL_PATH)/python3.7/bin/pyvenv-3.7:$(TARGET_COPY_OUT_VENDOR)/bin/pyvenv-3.7 )
					
PRODUCT_COPY_FILES += $(call find-copy-subdir-files,*,$(LOCAL_PATH)/python3.7/lib/python3.7,$(TARGET_COPY_OUT_VENDOR)/lib/python3.7)

參考:
http://blog.sina.com.cn/s/blog_67119e9a0102y31t.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章