diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..6693f51 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +# ignore all generated files +openssl-* +.DS_Store diff --git a/README.md b/README.md index 8b915fa..7ba0415 100755 --- a/README.md +++ b/README.md @@ -1,6 +1,26 @@ # OpenSSL for Android Automatically compile static OpenSSL(3.2.*) library for Android by Github Actions. +Usage: +1. Requires installed Android NDK. The location can be set using `ANDROID_NDK_LOCAL_PLATFORM` environment variable but the script attempts to locate the NDK for macOS and Linux if the environment variable is not provided. +1. To build latest OpenSSL use: + ``` + openssl_build.sh [android_target_abi | clean] [android_target_api | default] + ``` + The two parameters are: + * `android_target_abi` - one of: + * `armeabi-v7a`, `arm64-v8a`, `x86`, `x86_64` - ABI to build (`arm64-v8a` is default if not provided on command line) + * `clean` - Removes all local output files to force a fresh rebuild + * `android_target_api` - specific API level to target or `default` to use the default level from the NDK (`default` is used if not provided on command line) +1. OpenSSL is pulled down based on the environment variable `OPENSSL_VERSION` (defaults to `3.2.1`) +1. Output is placed in the local folder under `openssl-[android_target_abi]`. For example, arm64 is located under `openssl-arm64-v8a`. + +To build everything using default target API level: +``` +./tc3-android-build-wrapper.sh +``` +Output is placed in `/tmp/build_openssl_android.log` + ## Android `armeabi`、`mips`、`mips64` targets are no longer supported with NDK R17+. * [ ] armeabi @@ -33,4 +53,4 @@ Automatically compile static OpenSSL(3.2.*) library for Android by Github Action | 2021.09.08 | OpenSSL 1.1.1l | | 2021.03.29 | OpenSSL 1.1.1k | | 2021.02.18 | OpenSSL 1.1.1j | -| 2021.01.20 | OpenSSL 1.1.1i | \ No newline at end of file +| 2021.01.20 | OpenSSL 1.1.1i | diff --git a/openssl_build.sh b/openssl_build.sh index 0f10c93..4ba74f4 100755 --- a/openssl_build.sh +++ b/openssl_build.sh @@ -1,62 +1,157 @@ -#!/bin/bash -e +#!/bin/bash +# identify which openssl version we require +OPENSSL_VERSION="${OPENSSL_VERSION:-3.2.1}" + +# modified by ABr WORK_PATH=$(cd "$(dirname "$0")";pwd) -ANDROID_NDK_PATH=${WORK_PATH}/android-ndk-r20b -OPENSSL_SOURCES_PATH=${WORK_PATH}/openssl-3.3.0 +ANDROID_NDK_PATH='' +OPENSSL_SOURCES_PATH=${WORK_PATH}/openssl-$OPENSSL_VERSION ANDROID_TARGET_API=$1 ANDROID_TARGET_ABI=$2 -OUTPUT_PATH=${WORK_PATH}/openssl_3.3.0_${ANDROID_TARGET_ABI} +OUTPUT_PATH=${WORK_PATH}/openssl_${OPENSSL_VERSION}_${ANDROID_TARGET_ABI} -OPENSSL_TMP_FOLDER=/tmp/openssl_${ANDROID_TARGET_ABI} -mkdir -p ${OPENSSL_TMP_FOLDER} -cp -r ${OPENSSL_SOURCES_PATH}/* ${OPENSSL_TMP_FOLDER} +# caller may pass in target ABI and API +ANDROID_TARGET_ABI="${1:-arm64-v8a}" ; shift +ANDROID_TARGET_API="${1:-default}" ; shift + +# special surprise: if ANDROID_TARGET_API is 'clean' then clean up... +if [ x"$ANDROID_TARGET_API" = xclean ] ; then + echo 'Cleaning project...' + rm -fR ./openssl-* /tmp/openssl-* + exit $? +fi + +# caller must set ANDROID_NDK_HOME +[ x"$ANDROID_NDK_HOME" = x ] && echo 'Must set ANDROID_NDK_HOME' && exit 1 + +# caller may set ANDROID_NDK_LOCAL_PLATFORM or use computed default +unameOut="`uname -s | dos2unix`" +case "${unameOut}" in + Linux*) machine=linux;; + Darwin*) machine=mac;; + CYGWIN*) machine=cygwin;; + MINGW*) machine=mingw;; + *) machine="UNKNOWN:${unameOut}" +esac +if [ x"$ANDROID_NDK_LOCAL_PLATFORM" = x ] ; then + if [ x"$machine" = xmac ] ; then + # apple silicon or intel? + ANDROID_NDK_LOCAL_PLATFORM=darwin-`uname -m` + elif [ x"$machine" = xlinux ] ; then + ANDROID_NDK_LOCAL_PLATFORM=linux-`uname -m` + fi +fi +[ x"$ANDROID_NDK_LOCAL_PLATFORM" = x ] && echo 'Must set ANDROID_NDK_LOCAL_PLATFORM' && exit 1 + +# we must have platform bin folder for NDK build to work +required_ndk_bin_folder="$ANDROID_NDK_HOME/toolchains/llvm/prebuilt/$ANDROID_NDK_LOCAL_PLATFORM" +[ ! -d "$required_ndk_bin_folder" ] && echo "Cannot locate required NDK '$required_ndk_bin_folder'" && exit 1 + +function pull_openssl { + # copy from web + if [ ! -f "${WORK_PATH}/openssl-${OPENSSL_VERSION}.tar.gz" ]; then + echo "Pull down 'https://www.openssl.org/source/openssl-${OPENSSL_VERSION}.tar.gz'..." + rm -fR "$OPENSSL_SOURCES_PATH" + curl -fL "https://www.openssl.org/source/openssl-${OPENSSL_VERSION}.tar.gz" -o "${WORK_PATH}/openssl-${OPENSSL_VERSION}.tar.gz" + curl -fL "https://www.openssl.org/source/openssl-${OPENSSL_VERSION}.tar.gz.sha256" -o "${WORK_PATH}/openssl-${OPENSSL_VERSION}.tar.gz.sha256" + DIGEST=$( cat ${WORK_PATH}/openssl-${OPENSSL_VERSION}.tar.gz.sha256 ) + + if [[ "$(shasum -a 256 "openssl-${OPENSSL_VERSION}.tar.gz" | awk '{ print " "$1}')" != "${DIGEST}" ]] + then + echo "openssl-${OPENSSL_VERSION}.tar.gz: checksum mismatch" + exit 1 + fi + rm -f "${SCRIPT_DIR}/../openssl-${OPENSSL_VERSION}.tar.gz.sha256" + fi + + # update + if [ ! -d "$OPENSSL_SOURCES_PATH" ] ; then + echo "Extract into '$OPENSSL_SOURCES_PATH'..." + tar xzf "${WORK_PATH}/openssl-${OPENSSL_VERSION}.tar.gz" || exit $? + rm -fR "$OPENSSL_TMP_FOLDER" + fi + return 0 +} function build_library { - mkdir -p ${OUTPUT_PATH} - make && make install - rm -rf ${OPENSSL_TMP_FOLDER} - rm -rf ${OUTPUT_PATH}/bin - rm -rf ${OUTPUT_PATH}/share - rm -rf ${OUTPUT_PATH}/ssl - rm -rf ${OUTPUT_PATH}/lib/engines* - rm -rf ${OUTPUT_PATH}/lib/pkgconfig - rm -rf ${OUTPUT_PATH}/lib/ossl-modules - echo "Build completed! Check output libraries in ${OUTPUT_PATH}" + local l_rc=0 + + echo "mkdir -p '${OUTPUT_PATH}'" + mkdir -p "${OUTPUT_PATH}" + + echo "make && make install" + make && make install + l_rc=$? ; [ $l_rc -ne 0 ] && return $l_rc + + echo 'Cleaning up build...' + rm -rf ${OPENSSL_TMP_FOLDER} + rm -rf ${OUTPUT_PATH}/bin + rm -rf ${OUTPUT_PATH}/share + rm -rf ${OUTPUT_PATH}/ssl + rm -rf ${OUTPUT_PATH}/lib/engines* + rm -rf ${OUTPUT_PATH}/lib/pkgconfig + rm -rf ${OUTPUT_PATH}/lib/ossl-modules + echo '' + + echo "Build completed! Check output libraries in ${OUTPUT_PATH}" } -if [ "$ANDROID_TARGET_ABI" == "armeabi-v7a" ] -then - export ANDROID_NDK_ROOT=${ANDROID_NDK_PATH} - PATH=$ANDROID_NDK_ROOT/toolchains/llvm/prebuilt/linux-x86_64/bin:$ANDROID_NDK_ROOT/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin:$ANDROID_NDK_ROOT/toolchains/aarch64-linux-android-4.9/prebuilt/linux-x86_64/bin:$PATH - cd ${OPENSSL_TMP_FOLDER} - ./Configure android-arm -D__ANDROID_API__=${ANDROID_TARGET_API} -static no-asm no-shared no-tests --prefix=${OUTPUT_PATH} - build_library - -elif [ "$ANDROID_TARGET_ABI" == "arm64-v8a" ] -then - export ANDROID_NDK_ROOT=${ANDROID_NDK_PATH} - PATH=$ANDROID_NDK_ROOT/toolchains/llvm/prebuilt/linux-x86_64/bin:$ANDROID_NDK_ROOT/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin:$ANDROID_NDK_ROOT/toolchains/aarch64-linux-android-4.9/prebuilt/linux-x86_64/bin:$PATH - cd ${OPENSSL_TMP_FOLDER} - ./Configure android-arm64 -D__ANDROID_API__=${ANDROID_TARGET_API} -static no-asm no-shared no-tests --prefix=${OUTPUT_PATH} - build_library - -elif [ "$ANDROID_TARGET_ABI" == "x86" ] -then - export ANDROID_NDK_ROOT=${ANDROID_NDK_PATH} - PATH=$ANDROID_NDK_ROOT/toolchains/llvm/prebuilt/linux-x86_64/bin:$ANDROID_NDK_ROOT/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin:$ANDROID_NDK_ROOT/toolchains/aarch64-linux-android-4.9/prebuilt/linux-x86_64/bin:$PATH - cd ${OPENSSL_TMP_FOLDER} - ./Configure android-x86 -D__ANDROID_API__=${ANDROID_TARGET_API} -static no-asm no-shared no-tests --prefix=${OUTPUT_PATH} - build_library - -elif [ "$ANDROID_TARGET_ABI" == "x86_64" ] -then - export ANDROID_NDK_ROOT=${ANDROID_NDK_PATH} - PATH=$ANDROID_NDK_ROOT/toolchains/llvm/prebuilt/linux-x86_64/bin:$ANDROID_NDK_ROOT/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin:$ANDROID_NDK_ROOT/toolchains/aarch64-linux-android-4.9/prebuilt/linux-x86_64/bin:$PATH - cd ${OPENSSL_TMP_FOLDER} - ./Configure android-x86_64 -D__ANDROID_API__=${ANDROID_TARGET_API} -static no-asm no-shared no-tests --prefix=${OUTPUT_PATH} - build_library - -else - echo "Unsupported target ABI: $ANDROID_TARGET_ABI" - exit 1 +# derived variables +WORK_PATH=$(cd "$(dirname "$0")";pwd) +ANDROID_NDK_PATH="$ANDROID_NDK_HOME" +OPENSSL_SOURCES_PATH=${WORK_PATH}/openssl-$OPENSSL_VERSION +OUTPUT_PATH=${WORK_PATH}/openssl-$OPENSSL_VERSION_${ANDROID_TARGET_ABI} +OPENSSL_TMP_FOLDER=/tmp/openssl-${ANDROID_TARGET_ABI} + +pull_openssl || exit $? + +mkdir -p ${OPENSSL_TMP_FOLDER} +echo "rsync -av '${OPENSSL_SOURCES_PATH}/' '${OPENSSL_TMP_FOLDER}'" +rsync -av "${OPENSSL_SOURCES_PATH}/" "${OPENSSL_TMP_FOLDER}" + +# PATH is set the same for all build variants +export ANDROID_NDK_ROOT="${ANDROID_NDK_PATH}" +PATH="$ANDROID_NDK_ROOT/toolchains/llvm/prebuilt/$ANDROID_NDK_LOCAL_PLATFORM/bin:$ANDROID_NDK_ROOT/toolchains/arm-linux-androideabi-4.9/prebuilt/$ANDROID_NDK_LOCAL_PLATFORM/bin:$ANDROID_NDK_ROOT/toolchains/aarch64-linux-android-4.9/prebuilt/$ANDROID_NDK_LOCAL_PLATFORM/bin:$PATH" + +# map the platform identifier from Android to OpenSSL (e.g. arm64-v8a -> android-arm64) +case "$ANDROID_TARGET_ABI" in + armeabi-v7a) openssl_platform='android-arm';; + arm64-v8a) openssl_platform='android-arm64';; + x86) openssl_platform='android-x86';; + x86_64) openssl_platform='android-x86_64';; + *) echo "Unsupported ANDROID_TARGET_ABI '$ANDROID_TARGET_ABI'" ; exit 1;; +esac + +echo "Using ANDROID_NDK_ROOT='$ANDROID_NDK_ROOT'..." +echo "Using PATH='$PATH'..." +echo '' + +# the remainder is the same for all :) +echo "cd '${OPENSSL_TMP_FOLDER}'" +cd "${OPENSSL_TMP_FOLDER}" +echo '' + +# by default __ANDROID_API__ is defined and we get warnings if we redefine +the_tmp="/tmp/openssl_build_$$.sh" +echo "#!$SHELL" >"$the_tmp" +# ABr: solve "relocation R_AARCH64_ADR_PREL_PG_HI21 cannot be used against symbol 'bio_type_lock'; recompile with -fPIC" +echo 'export CFLAGS=-fPIC' >>"$the_tmp" +echo "./Configure $openssl_platform \\" >>"$the_tmp" +if [ x"$ANDROID_TARGET_API" != xdefault ] ; then + # see https://github.com/openssl/openssl/issues/18561#issuecomment-1155298077 + echo " -U__ANDROID_API__ -D__ANDROID_API__=${ANDROID_TARGET_API} \\" >>"$the_tmp" fi +echo " -static no-asm no-shared no-tests --prefix='${OUTPUT_PATH}'" >>"$the_tmp" +echo 'Running configure...' +chmod +x "$the_tmp" +cat "$the_tmp" +"$the_tmp" +the_rc=$? +rm -f "$the_tmp" +[ $the_rc -ne 0 ] && exit $the_rc +echo '' + +build_library +exit $? + diff --git a/tc3-android-build-wrapper.sh b/tc3-android-build-wrapper.sh new file mode 100755 index 0000000..8a35fed --- /dev/null +++ b/tc3-android-build-wrapper.sh @@ -0,0 +1,19 @@ +#!/bin/bash +# tc3-android-build-wrapper.sh, ABr +# +# Build openssl for android with mods to compiled correctly +echo 'build_openssl_android: Start...' +echo '' +first_flag=0 +for i in armeabi-v7a arm64-v8a x86 x86_64 ; do + if [ x"$first_flag" = x1 ] ; then + echo "***$i: clean" + ./openssl_build.sh $i clean || break + echo '' + first_flag=0 + fi + echo "***$i: build" + ./openssl_build.sh $i || break + echo '' +done + diff --git a/tc3-android-update-onedrive.sh b/tc3-android-update-onedrive.sh new file mode 100755 index 0000000..9fa541f --- /dev/null +++ b/tc3-android-update-onedrive.sh @@ -0,0 +1,22 @@ +#!/bin/bash +# tc3-android-update-onedrive.sh, ABr +# Update target android openssl libraries on OneDrive external + +tc3_dir="${tc3_dir:-$HOME/proj/git/src/triplecyber.visualstudio.com/abruce-dev/Tc32}" +openssl_ver="${openssl_ver:-3.2.1}" +for i in arm64-v8a armeabi-v7a x86 x86_64 ; do + echo "Processing $i..." + abi=$i + src_dir=./openssl-$abi + tgt_dir="$tc3_dir"/External/openssl/android/$openssl_ver/$abi + echo "mkdir -p '$tgt_dir'" + mkdir -p "$tgt_dir" + echo "rm -fR '$tgt_dir'/*" + rm -fR "$tgt_dir"/* + the_rc=$? ; [ $the_rc -ne 0 ] && break + echo "cp -R '$src_dir'/* '$tgt_dir'/" + yes | cp -R "$src_dir"/* "$tgt_dir"/ + the_rc=$? ; [ $the_rc -ne 0 ] && break + echo '' +done +