将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

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