文章目錄
注:因此python需要交叉編譯,使用系統自帶python3執行命令的過程中,可能會出現找不到函數的去情況:
交叉編譯Python的時候最好保證電腦上的Python版本和要編譯的Python版本一致,即先編譯安裝Linux版本,再編譯arm版本。
1. 源碼下載
從https://www.python.org/下載源碼。
我這裏下載最新的 Python3.7.4。
2. 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)