android_whl_env_prepare.sh 6.0 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155
#!/bin/bash -e

# Installing package by pkg in termux is unwise because pkg will upgrade
# package to the latest version which is undesired sometimes.  We will
# use apt as default package tool. If your env is already broken,e.g.
# clang does not work, you can execute following commands to fix it:
# pkg update
# pkg upgrade

SRC_DIR=$(readlink -f "`dirname $0`/../../../")
cd ${SRC_DIR}
source scripts/whl/android/utils.sh

function install_apt_package() {
    APT_PACKAGE="proot git wget clang cmake libandroid-spawn binutils build-essential ninja texinfo patchelf python"
    echo "try install: ${APT_PACKAGE}"
    apt install ${APT_PACKAGE}
    echo "check termux status by running: clang --version"
    log=`clang --version || true`
    if [[ "${log}" =~ "clang version" ]]; then
        echo "valid env after installing apt package"
    else
        echo "Failed to run clang command, please check termux env!!! You can run: pkg update && pkg upgrade to try to solve it"
        echo "raw log: ${log}"
        exit -1
    fi

}

function patch_termux_env() {
    # do not try to modify other project build files to adapt to only-llvm environment
    echo "many projects can not build without gcc libs, so we create a fake gcc libs linked to librt"
    RT_LIB_TARGET="${PREFIX}/lib/librt.so"
    if [ -e ${RT_LIB_TARGET} ];then
        echo "find librt.so and link it to libgcc.so"
        GCC_LIB_TARGET="${PREFIX}/lib/libgcc.so"
        if [ -e ${GCC_LIB_TARGET} ];then
            echo "already find: ${GCC_LIB_TARGET} skip it"
        else
            create_libgcc_cmd="ln -s ${RT_LIB_TARGET} ${GCC_LIB_TARGET}"
            echo "run cmd: $create_libgcc_cmd"
            ${create_libgcc_cmd}
        fi
    else
        echo "broken termux env, can not find librt.so"
        exit -1
    fi
}

function build_python() {
    # Up to now many tools (build multi python3) are not supported in termux so that we have to build them from source.
    # This function will be changed when some tools are supported in termux, e.g. pyenv.
    mge_python_env_root="${HOME}/mge_python_env"
    mkdir -p ${mge_python_env_root}
    cd ${mge_python_env_root}

    if [ -e ${PREFIX}/local/lib/libffi.a ];then
        echo "always find libffi, skip build it"
    else
        echo "build libffi for python module"
        rm -rf libffi
        git clone https://github.com/libffi/libffi.git
        cd libffi
        termux-chroot "./autogen.sh && ./configure && make -j$(nproc) && make install"
        # remove dynamic lib to force python to use static lib
        rm ${PREFIX}/local/lib/libffi.so*
    fi

    if [ -e ${PREFIX}/local/lib/libz.a ];then
        echo "always find libzlib, skip build it"
    else
        echo "build zlib for python module"
        rm -rf zlib
        git clone https://github.com/madler/zlib.git
        cd zlib
        termux-chroot "CFLAGS=\"-O3 -fPIC\" ./configure && make -j$(nproc) && make install"
        # remove dynamic lib to force python to use static lib
        rm ${PREFIX}/local/lib/libz.so*
    fi

    cpython_repo_dir=${mge_python_env_root}/cpython
    if [ -d ${cpython_repo_dir}/.git ];then
        echo "already find cpython repo"
        cd ${cpython_repo_dir}
        git reset --hard
        git clean -xdf
        git fetch
    else
        cd ${mge_python_env_root}
        rm -rf ${cpython_repo_dir}
        git clone https://github.com/python/cpython.git
    fi
    for ver in ${ALL_PYTHON}
    do
        install_dir=${mge_python_env_root}/${ver}/install
        if [ -e ${install_dir}/bin/python3 ];then
            echo "always find python3, skip build it"
        else
            mkdir -p ${install_dir}
            echo "try build python: ${ver} to ${install_dir}"
            cd ${cpython_repo_dir}
            git reset --hard
            git clean -xdf
            git checkout v${ver}
            index=`awk -v a="${ver}" -v b="." 'BEGIN{print index(a,b)}'`
            sub_str=${ver:${index}}
            index_s=`awk -v a="${sub_str}" -v b="." 'BEGIN{print index(a,b)}'`
            ((finally_index = ${index} + ${index_s}))
            finally_verson=${ver:0:${finally_index}-1}
            MINOR_VER=${ver:${index}:${finally_index}-${index}-1}
            finally_verson="python${finally_verson}"
            echo "finally_verson is: ${finally_verson}"
            # apply patchs
            git apply ${SRC_DIR}/scripts/whl/android/patchs/*.patch
            if [[ ${MINOR_VER} -gt 8 ]]
            then
                echo "apply more patchs"
                git apply ${SRC_DIR}/scripts/whl/android/up_3_9_patch/*.patch
            fi

            termux-chroot "FLAGS=\"-D__ANDROID_API__=24 -Wno-unused-value -Wno-empty-body -Qunused-arguments -Wno-error\" \
                ./configure CFLAGS=\"${FLAGS}\" CPPFLAGS=\"${FLAGS}\" CC=clang CXX=clang++ --enable-shared  --prefix=${install_dir} \
                && sed -i 's/-Werror=implicit-function-declaration//g' Makefile && \
                sed -i 's/\$(LN) -f \$(INSTSONAME)/cp \$(INSTSONAME)/g' Makefile && make -j$(nproc) && make install"

            # after building successfully, patchelf to make python work out of termux-chroot env
            cd ${install_dir}/bin
            # Some python versions won't link to python3 automatically, so we create link manually here'
            rm -rf python3
            if [[ ${MINOR_VER} -gt 7 ]]
            then
                echo "python3 remove suffix m after 3.8"
                patchelf --add-rpath ${install_dir}/lib ${finally_verson}
                cp ${finally_verson} python3
            else
                echo "python3 with suffix m before 3.8, add it"
                patchelf --add-rpath ${install_dir}/lib "${finally_verson}m"
                cp "${finally_verson}m" ${finally_verson}
                cp ${finally_verson} python3
            fi
            echo "finally try run python3"
            ./python3 --version
            ./python3 -m pip install --upgrade pip
            ./python3 -m pip install numpy wheel

        fi
    done
}

############install env now###########
echo "run at root dir: ${SRC_DIR}"
check_termux_env
install_apt_package
patch_termux_env
build_python