diff options
Diffstat (limited to 'packaging/android/qmake-build.sh')
-rwxr-xr-x | packaging/android/qmake-build.sh | 369 |
1 files changed, 369 insertions, 0 deletions
diff --git a/packaging/android/qmake-build.sh b/packaging/android/qmake-build.sh new file mode 100755 index 000000000..6b4321ad2 --- /dev/null +++ b/packaging/android/qmake-build.sh @@ -0,0 +1,369 @@ +#!/bin/bash +# +# build a multi architecture package for Android +# +# this requires Qt5.14 or newer with matching NDK +# +# the packaging/android/android-build-setup.sh sets up an environment that works for this + +set -eu + +exec 1> >(tee ./android-build.log) 2>&1 + +# get the absolute path +pushd "$(dirname "$0")/../../" +export SUBSURFACE_SOURCE=$PWD +cd .. +export BUILDROOT=$PWD +popd + +# Set build defaults +# is this a release or debug build +BUILD_TYPE=Debug + +# and now we need a monotonic build number... +if [ ! -f ./buildnr.dat ] ; then + BUILDNR=0 +else + BUILDNR=$(cat ./buildnr.dat) +fi +BUILDNR=$((BUILDNR+1)) +echo "${BUILDNR}" > ./buildnr.dat + +# Read build variables +source $SUBSURFACE_SOURCE/packaging/android/variables.sh + +# this assumes that the Subsurface source directory is in the same +# directory hierarchy as the SDK and NDK +export ANDROID_NDK_ROOT="$SUBSURFACE_SOURCE/../$ANDROID_NDK" +export ANDROID_SDK_ROOT="$SUBSURFACE_SOURCE/.." + +QUICK="" +ARCHITECTURES="" +BUILD_ABIS="" +versionOnly="" + +while [ "$#" -gt 0 ] ; do + case "$1" in + Release|release) + shift + BUILD_TYPE=Release + ;; + Debug|debug) + # this is the default - still need to eat the argument if given + BUILD_TYPE=Debug + shift + ;; + -buildnr) + shift + BUILDNR=$1 + shift + ;; + -version) + # only update the version info without rebuilding + # this is useful when working with Xcode + versionOnly="1" + ;; + arm|arm64|x86|x86_64) + ARCHITECTURES=$1 + shift + ;; + -quick) + QUICK="1" + shift + ;; + *) + echo "Unknown argument $1" + exit 1 + ;; + esac +done + +mkdir -p "$BUILDROOT"/subsurface-mobile-build +pushd "$BUILDROOT"/subsurface-mobile-build + +# set up the Subsurface versions by hand +GITVERSION=$(cd "$SUBSURFACE_SOURCE" ; git describe --abbrev=12) +CANONICALVERSION=$(echo "$GITVERSION" | sed -e 's/-g.*$// ; s/^v//' | sed -e 's/-/./') +MOBILEVERSION=$(grep MOBILE "$SUBSURFACE_SOURCE"/cmake/Modules/version.cmake | cut -d\" -f 2) +echo "#define GIT_VERSION_STRING \"$GITVERSION\"" > ssrf-version.h +echo "#define CANONICAL_VERSION_STRING \"$CANONICALVERSION\"" >> ssrf-version.h +echo "#define MOBILE_VERSION_STRING \"$MOBILEVERSION\"" >> ssrf-version.h +SUBSURFACE_MOBILE_VERSION="$MOBILEVERSION ($CANONICALVERSION)" +popd + +if [ "$versionOnly" = "1" ] ; then + exit 0 +fi + +# pick the Qt setup and show the configuration info +if [ -n "${QT5_ANDROID+X}" ] ; then + echo "Using Qt5 in $QT5_ANDROID" +elif [ -d "$SUBSURFACE_SOURCE/../${LATEST_QT}" ] ; then + export QT5_ANDROID=$SUBSURFACE_SOURCE/../${LATEST_QT} +else + echo "Cannot find Qt 5.12 or newer under $SUBSURFACE_SOURCE/.." + exit 1 +fi + +QMAKE=$QT5_ANDROID/android/bin/qmake +echo $QMAKE +$QMAKE -query + + +# if we are just doing a quick rebuild, don't bother with any of the dependencies + +if [ "$QUICK" = "" ] ; then + + # build google maps plugin + # this is the easy one as it uses qmake which ensures things get built for all platforms, etc + "${SUBSURFACE_SOURCE}"/scripts/get-dep-lib.sh singleAndroid . googlemaps + QT_PLUGINS_PATH=$($QMAKE -query QT_INSTALL_PLUGINS) + GOOGLEMAPS_BIN=libqtgeoservices_googlemaps.so + if [ ! -e "$QT_PLUGINS_PATH"/geoservices/$GOOGLEMAPS_BIN ] || [ googlemaps/.git/HEAD -nt "$QT_PLUGINS_PATH"/geoservices/$GOOGLEMAPS_BIN ] ; then + mkdir -p googlemaps-build + pushd googlemaps-build + $QMAKE ../googlemaps/googlemaps.pro + make -j4 + # $QMAKE -install qinstall -exe $GOOGLEMAPS_BIN "$QT_PLUGINS_PATH"/geoservices/$GOOGLEMAPS_BIN + make install + popd + fi +fi + +# autoconf based libraries are harder +export TOOLCHAIN="$ANDROID_NDK_ROOT"/toolchains/llvm/prebuilt/linux-x86_64 +PATH=$TOOLCHAIN/bin:$PATH +export ANDROID_NDK_HOME=$ANDROID_NDK_ROOT # redundant, but that's what openssl wants + +# build default architectures, or the given one? +if [ "$ARCHITECTURES" = "" ] ; then + ARCHITECTURES="armv7a aarch64" +fi + +for ARCH in $ARCHITECTURES ; do + echo "START building libraries for $ARCH" + echo "=====================================" + + # it would of course be too easy to use these terms consistently, so let's not + if [ "$ARCH" = "armv7a" ] ; then + EABI="eabi" + BINUTIL_ARCH="arm" + OPENSSL_ARCH="arm" + ANDROID_ABI="armeabi-v7a" + else + EABI="" + BINUTIL_ARCH="aarch64" + OPENSSL_ARCH="arm64" + ANDROID_ABI="arm64-v8a" + fi + BUILD_ABIS="$BUILD_ABIS $ANDROID_ABI" + + export TARGET=$ARCH-linux-android + + export AR=$TOOLCHAIN/bin/$BINUTIL_ARCH-linux-android$EABI-ar + export AS=$TOOLCHAIN/bin/$BINUTIL_ARCH-linux-android$EABI-as + export CC=$TOOLCHAIN/bin/$TARGET$EABI$ANDROID_PLATFORM_LEVEL-clang + export CXX=$TOOLCHAIN/bin/$TARGET$EABI$ANDROID_PLATFORM_LEVEL-clang++ + export LD=$TOOLCHAIN/bin/$BINUTIL_ARCH-linux-android$EABI-ld + export RANLIB=$TOOLCHAIN/bin/$BINUTIL_ARCH-linux-android$EABI-ranlib + export STRIP=$TOOLCHAIN/bin/$BINUTIL_ARCH-linux-android$EABI-strip + + # set up an install root and create part of the directory structure so the openssl + # manual install below doesn't fail + export PREFIX="$BUILDROOT"/install-root-"$ANDROID_ABI" + mkdir -p "$PREFIX"/include + mkdir -p "$PREFIX"/lib/pkgconfig + export PKG_CONFIG_PATH=$PREFIX/lib/pkgconfig + + if [ "$QUICK" = "" ] ; then + "${SUBSURFACE_SOURCE}"/scripts/get-dep-lib.sh singleAndroid . openssl + if [ ! -e "$PKG_CONFIG_PATH/libssl.pc" ] ; then + # openssl build fails with these set + export SYSROOT="" + export CFLAGS="" + export CPPFLAGS="" + export CXXFLAGS="" + + mkdir -p openssl-build-"$ARCH" + cp -r openssl/* openssl-build-"$ARCH" + pushd openssl-build-"$ARCH" + perl -pi -e 's/-mandroid//g' Configure + ./Configure shared android-"$OPENSSL_ARCH" no-ssl2 no-ssl3 no-comp no-hw no-engine no-asm \ + --prefix="$PREFIX" -DOPENSSL_NO_UI_CONSOLE -DOPENSSL_NO_STDIO \ + -D__ANDROID_API__=$ANDROID_PLATFORM_LEVEL + make depend + # follow the suggestions here: https://doc.qt.io/qt-5/android-openssl-support.html + make SHLIB_VERSION_NUMBER= SHLIB_EXT=_1_1.so build_libs + + cp -RL include/openssl $PREFIX/include/openssl + cp libcrypto.a $PREFIX/lib + cp libcrypto_1_1.so* $PREFIX/lib + cp libssl.a $PREFIX/lib + cp libssl_1_1.so* $PREFIX/lib + cp *.pc $PKG_CONFIG_PATH + + popd + fi + + fi + + # autoconf seems to get lost without this -- but openssl fails if these are set + SYSROOT="$ANDROID_NDK_ROOT"/toolchains/llvm/prebuilt/linux-x86_64/sysroot + CFLAGS="--sysroot=${SYSROOT} -fPIC" + CPPFLAGS="--sysroot=${SYSROOT} -fPIC" + CXXFLAGS="--sysroot=${SYSROOT} -fPIC" + + if [ "$QUICK" = "" ] ; then + "${SUBSURFACE_SOURCE}"/scripts/get-dep-lib.sh singleAndroid . sqlite + if [ ! -e "$PKG_CONFIG_PATH/sqlite3.pc" ] ; then + mkdir -p sqlite-build-"$ARCH" + pushd sqlite-build-"$ARCH" + ../sqlite/configure --host="$TARGET" --prefix="$PREFIX" --enable-static --disable-shared + make + make install + popd + fi + + "${SUBSURFACE_SOURCE}"/scripts/get-dep-lib.sh singleAndroid . libxml2 + if [ ! -e libxml2/configure ] ; then + pushd libxml2 + autoreconf --install + popd + fi + if [ ! -e "$PKG_CONFIG_PATH/libxml-2.0.pc" ] ; then + mkdir -p libxml2-build-"$ARCH" + pushd libxml2-build-"$ARCH" + ../libxml2/configure --host="$TARGET" --prefix="$PREFIX" --without-python --without-iconv --enable-static --disable-shared + perl -pi -e 's/runtest\$\(EXEEXT\)//' Makefile + perl -pi -e 's/testrecurse\$\(EXEEXT\)//' Makefile + make + make install + popd + fi + + "${SUBSURFACE_SOURCE}"/scripts/get-dep-lib.sh singleAndroid . libxslt + if [ ! -e libxslt/configure ] ; then + pushd libxslt + autoreconf --install + popd + fi + if [ ! -e "$PKG_CONFIG_PATH/libxslt.pc" ] ; then + mkdir -p libxslt-build-"$ARCH" + pushd libxslt-build-"$ARCH" + ../libxslt/configure --host="$TARGET" --prefix="$PREFIX" --with-libxml-prefix="$PREFIX" --without-python --without-crypto --enable-static --disable-shared + make + make install + popd + fi + + "${SUBSURFACE_SOURCE}"/scripts/get-dep-lib.sh singleAndroid . libzip + if [ ! -e "$PKG_CONFIG_PATH/libzip.pc" ] ; then + # libzip expects a predefined macro that isn't there for our compiler + pushd libzip + git reset --hard + sed -i 's/SIZEOF_SIZE_T/__SIZEOF_SIZE_T__/g' lib/compat.h + # also, don't deal with manuals and bzip2 + sed -i 's/ADD_SUBDIRECTORY(man)//' CMakeLists.txt + sed -i 's/^FIND_PACKAGE(ZLIB/#&/' CMakeLists.txt + popd + mkdir -p libzip-build-"$ARCH" + pushd libzip-build-"$ARCH" + cmake \ + -DCMAKE_C_COMPILER="$CC" \ + -DCMAKE_LINKER="$CC" \ + -DCMAKE_INSTALL_PREFIX="$PREFIX" \ + -DCMAKE_INSTALL_LIBDIR="lib" \ + -DBUILD_SHARED_LIBS=OFF \ + -DCMAKE_DISABLE_FIND_PACKAGE_BZip2=TRUE \ + -DZLIB_VERSION_STRING=1.2.7 \ + -DZLIB_LIBRARY=z \ + ../libzip/ + make + make install + popd + fi + + "${SUBSURFACE_SOURCE}"/scripts/get-dep-lib.sh singleAndroid . libgit2 + if [ ! -e "$PKG_CONFIG_PATH/libgit2.pc" ] ; then + # We don't want to find the HTTP_Parser package of the build host by mistake + mkdir -p libgit2-build-"$ARCH" + pushd libgit2-build-"$ARCH" + cmake \ + -DCMAKE_C_COMPILER="$CC" \ + -DCMAKE_LINKER="$CC" \ + -DBUILD_CLAR=OFF -DBUILD_SHARED_LIBS=OFF \ + -DCMAKE_INSTALL_PREFIX="$PREFIX" \ + -DCURL=OFF \ + -DUSE_SSH=OFF \ + -DOPENSSL_SSL_LIBRARY="$PREFIX"/lib/libssl_1_1.so \ + -DOPENSSL_CRYPTO_LIBRARY="$PREFIX"/lib/libcrypto_1_1.so \ + -DOPENSSL_INCLUDE_DIR="$PREFIX"/include \ + -D_OPENSSL_VERSION="${OPENSSL_VERSION}" \ + -DCMAKE_DISABLE_FIND_PACKAGE_HTTP_Parser=TRUE \ + ../libgit2/ + make + make install + # Patch away pkg-config dependency to zlib, its there, i promise + perl -pi -e 's/^(Requires.private:.*)zlib(.*)$/$1 $2/' "$PKG_CONFIG_PATH"/libgit2.pc + popd + fi + + fi # QUICK + + CURRENT_SHA=$(cd "$SUBSURFACE_SOURCE"/libdivecomputer ; git describe) + PREVIOUS_SHA=$(cat "libdivecomputer-${ARCH}.SHA" 2>/dev/null || echo) + if [ ! "$CURRENT_SHA" = "$PREVIOUS_SHA" ] || [ ! -e "$PKG_CONFIG_PATH/libdivecomputer.pc" ] ; then + mkdir -p libdivecomputer-build-"$ARCH" + pushd libdivecomputer-build-"$ARCH" + "$SUBSURFACE_SOURCE"/libdivecomputer/configure --host="$TARGET" --prefix="$PREFIX" --enable-static --disable-shared --enable-examples=no + make + make install + popd + echo "$CURRENT_SHA" > "libdivecomputer-${ARCH}.SHA" + fi + echo "DONE building libraries for $ARCH" + echo "=====================================" +done # ARCH + +#"${SUBSURFACE_SOURCE}"/scripts/get-dep-lib.sh singleAndroid . qt-android-cmake +# the Qt Android cmake addon runs androiddeployqt with '--verbose' which +# is, err, rather verbose. Let's not do that. +#sed -i -e 's/--verbose//' qt-android-cmake/AddQtAndroidApk.cmake + +# if this isn't just a quick rebuild, pull kirigami, icons, etc +if [ "$QUICK" = "" ] ; then + pushd "$SUBSURFACE_SOURCE" + bash ./scripts/mobilecomponents.sh + popd +fi + +# set up the final build +pushd "$BUILDROOT"/subsurface-mobile-build +rm -rf android-build +mkdir android-build +pushd "$SUBSURFACE_SOURCE"/android-mobile +tar c . | (cd "$BUILDROOT"/subsurface-mobile-build/android-build ; tar x) +popd + +# call qmake to set up the build +echo "Run qmake to setup the Subsurface-mobile build for all architectures" +$QMAKE BUILD_NR="$BUILDNR" BUILD_VERSION_NAME="$SUBSURFACE_MOBILE_VERSION" ANDROID_ABIS="$BUILD_ABIS" "$SUBSURFACE_SOURCE"/Subsurface-mobile-android.pro + + +# if this isn't just a quick rebuild compile the translations +if [ "$QUICK" = "" ] ; then + pushd "$SUBSURFACE_SOURCE"/translations + SRCS=$(ls ./*.ts | grep -v source) + popd + pushd "$SUBSURFACE_SOURCE"/packaging/android + mkdir -p translation-assets + for src in $SRCS; do + "$QT5_ANDROID"/android/bin/lrelease "$SUBSURFACE_SOURCE"/translations/"$src" -qm translation-assets/"${src/.ts/.qm}" + done + popd +fi + +# now build the Subsurface aab +make aab + |