Skip to content

Commit

Permalink
Merge bitcoin#17227: Qt: Add Android packaging support
Browse files Browse the repository at this point in the history
  • Loading branch information
laanwj authored and jagdeep sidhu committed Mar 24, 2021
1 parent 3de9d58 commit 8a273cf
Show file tree
Hide file tree
Showing 22 changed files with 234 additions and 1 deletion.
8 changes: 8 additions & 0 deletions .cirrus.yml
Expand Up @@ -176,3 +176,11 @@ task:
CI_USE_APT_INSTALL: "no"
PACKAGE_MANAGER_INSTALL: "echo" # Nothing to do
FILE_ENV: "./ci/test/00_setup_env_mac_host.sh"

task:
name: 'ARM64 Android APK [bionic]'
<< : *GLOBAL_TASK_TEMPLATE
container:
image: ubuntu:bionic
env:
FILE_ENV: "./ci/test/00_setup_env_android.sh"
17 changes: 17 additions & 0 deletions ci/test/00_setup_env_android.sh
@@ -0,0 +1,17 @@
#!/usr/bin/env bash
#
# Copyright (c) 2019-2020 The Bitcoin Core developers
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.

export LC_ALL=C.UTF-8

export CONTAINER_NAME=ci_android
export PACKAGES="clang llvm unzip openjdk-8-jdk gradle"

export ANDROID_API_LEVEL=28
export ANDROID_BUILD_TOOLS_VERSION=28.0.3
export ANDROID_NDK_VERSION=21.1.6352462
export ANDROID_TOOLS_URL=https://dl.google.com/android/repository/commandlinetools-linux-6609375_latest.zip

export SYSCOIN_CONFIG="--disable-ccache"
14 changes: 14 additions & 0 deletions ci/test/05_before_script.sh
Expand Up @@ -22,6 +22,20 @@ if [ -n "$XCODE_VERSION" ] && [ ! -f "$OSX_SDK_PATH" ]; then
DOCKER_EXEC curl --location --fail "${SDK_URL}/${OSX_SDK_BASENAME}" -o "$OSX_SDK_PATH"
fi

if [ -n "$ANDROID_TOOLS_URL" ]; then
ANDROID_TOOLS_PATH=$DEPENDS_DIR/sdk-sources/android-tools.zip
ANDROID_HOME="$DEPENDS_DIR"/SDKs/android
ANDROID_NDK_HOME=${ANDROID_HOME}/ndk/${ANDROID_NDK_VERSION}

DOCKER_EXEC curl --location --fail "${ANDROID_TOOLS_URL}" -o "$ANDROID_TOOLS_PATH"
DOCKER_EXEC mkdir -p "${ANDROID_HOME}/cmdline-tools"
DOCKER_EXEC unzip -o "$ANDROID_TOOLS_PATH" -d "${ANDROID_HOME}/cmdline-tools"
DOCKER_EXEC "yes | ${ANDROID_HOME}/cmdline-tools/tools/bin/sdkmanager --install \"build-tools;${ANDROID_BUILD_TOOLS_VERSION}\" \"platform-tools\" \"platforms;android-${ANDROID_API_LEVEL}\" \"ndk;${ANDROID_NDK_VERSION}\""

MAKE_COMMAND="ANDROID_SDK=${ANDROID_HOME} ANDROID_NDK=${ANDROID_NDK_HOME} make $MAKEJOBS -C depends HOST=aarch64-linux-android ANDROID_API_LEVEL=${ANDROID_API_LEVEL} ANDROID_TOOLCHAIN_BIN=${ANDROID_HOME}/ndk/${ANDROID_NDK_VERSION}/toolchains/llvm/prebuilt/linux-x86_64/bin/ $DEP_OPTS"
DOCKER_EXEC "$MAKE_COMMAND" HOST=aarch64-linux-android
fi

if [[ ${USE_MEMORY_SANITIZER} == "true" ]]; then
# Use BDB compiled using install_db4.sh script to work around linking issue when using BDB
# from depends. See https://github.com/bitcoin/bitcoin/pull/18288#discussion_r433189350 for
Expand Down
8 changes: 8 additions & 0 deletions ci/test/06_script_a.sh
Expand Up @@ -6,6 +6,14 @@

export LC_ALL=C.UTF-8

if [ -n "$ANDROID_TOOLS_URL" ]; then
DOCKER_EXEC make distclean || true
DOCKER_EXEC ./autogen.sh
DOCKER_EXEC ./configure $SYSCOIN_CONFIG --prefix=$DEPENDS_DIR/aarch64-linux-android || ( (DOCKER_EXEC cat config.log) && false)
DOCKER_EXEC "cd src/qt && make $MAKEJOBS && ANDROID_HOME=${ANDROID_HOME} ANDROID_NDK_HOME=${ANDROID_NDK_HOME} make apk"
exit 0
fi

SYSCOIN_CONFIG_ALL="--enable-suppress-external-warnings --disable-dependency-tracking --prefix=$DEPENDS_DIR/$HOST --bindir=$BASE_OUTDIR/bin --libdir=$BASE_OUTDIR/lib"
if [ -z "$NO_WERROR" ]; then
SYSCOIN_CONFIG_ALL="${SYSCOIN_CONFIG_ALL} --enable-werror"
Expand Down
16 changes: 16 additions & 0 deletions configure.ac
Expand Up @@ -734,6 +734,21 @@ case $host in
*android*)
dnl make sure android stays above linux for hosts like *linux-android*
TARGET_OS=android
case $host in
*x86_64*)
ANDROID_ARCH=x86_64
;;
*aarch64*)
ANDROID_ARCH=arm64-v8a
;;
*armv7a*)
ANDROID_ARCH=armeabi-v7a
;;
*i686*)
ANDROID_ARCH=i686
;;
*) AC_MSG_ERROR("Could not determine Android arch") ;;
esac
;;
*linux*)
TARGET_OS=linux
Expand Down Expand Up @@ -1874,6 +1889,7 @@ AC_SUBST(HAVE_BUILTIN_PREFETCH)
AC_SUBST(HAVE_MM_PREFETCH)
AC_SUBST(HAVE_STRONG_GETAUXVAL)
AC_SUBST(HAVE_WEAK_GETAUXVAL)
AC_SUBST(ANDROID_ARCH)
AC_CONFIG_FILES([Makefile src/Makefile doc/man/Makefile share/setup.nsi share/qt/Info.plist test/config.ini])
AC_CONFIG_FILES([contrib/devtools/split-debug.sh],[chmod +x contrib/devtools/split-debug.sh])
AM_COND_IF([HAVE_DOXYGEN], [AC_CONFIG_FILES([doc/Doxyfile])])
Expand Down
4 changes: 3 additions & 1 deletion depends/packages/qt.mk
Expand Up @@ -9,7 +9,7 @@ $(package)_qt_libs=corelib network widgets gui plugins testlib
$(package)_patches=fix_qt_pkgconfig.patch mac-qmake.conf fix_no_printer.patch no-xlib.patch
$(package)_patches+= fix_android_qmake_conf.patch fix_android_jni_static.patch dont_hardcode_pwd.patch
$(package)_patches+= drop_lrelease_dependency.patch no_sdk_version_check.patch
$(package)_patches+= fix_qpainter_non_determinism.patch fix_lib_paths.patch
$(package)_patches+= fix_qpainter_non_determinism.patch fix_lib_paths.patch fix_android_pch.patch

$(package)_qttranslations_file_name=qttranslations-$($(package)_suffix)
$(package)_qttranslations_sha256_hash=e1de58ed108b7e0a138815ea60fd46a2c4e1fc31396a707e5630e92de79c53de
Expand Down Expand Up @@ -165,6 +165,7 @@ $(package)_config_opts_android += -no-fontconfig
$(package)_config_opts_android += -L $(host_prefix)/lib
$(package)_config_opts_android += -I $(host_prefix)/include
$(package)_config_opts_android += -pch
$(package)_config_opts_android += -no-feature-vulkan

$(package)_config_opts_aarch64_android += -android-arch arm64-v8a
$(package)_config_opts_armv7a_android += -android-arch armeabi-v7a
Expand Down Expand Up @@ -224,6 +225,7 @@ define $(package)_preprocess_cmds
patch -p1 -i $($(package)_patch_dir)/fix_no_printer.patch && \
patch -p1 -i $($(package)_patch_dir)/fix_android_qmake_conf.patch && \
patch -p1 -i $($(package)_patch_dir)/fix_android_jni_static.patch && \
patch -p1 -i $($(package)_patch_dir)/fix_android_pch.patch && \
patch -p1 -i $($(package)_patch_dir)/no-xlib.patch && \
patch -p1 -i $($(package)_patch_dir)/fix_qpainter_non_determinism.patch &&\
patch -p1 -i $($(package)_patch_dir)/no_sdk_version_check.patch && \
Expand Down
10 changes: 10 additions & 0 deletions depends/patches/qt/fix_android_pch.patch
@@ -0,0 +1,10 @@
--- old/qtbase/mkspecs/common/android-base-head.conf
+++ new/qtbase/mkspecs/common/android-base-head.conf
@@ -73,6 +73,6 @@ CROSS_COMPILE = $$NDK_TOOLCHAIN_PATH/bin/$$NDK_TOOLS_PREFIX-
QMAKE_PCH_OUTPUT_EXT = .gch

QMAKE_CFLAGS_PRECOMPILE = -x c-header -c ${QMAKE_PCH_INPUT} -o ${QMAKE_PCH_OUTPUT}
-QMAKE_CFLAGS_USE_PRECOMPILE = -include ${QMAKE_PCH_OUTPUT_BASE}
+QMAKE_CFLAGS_USE_PRECOMPILE = -include-pch ${QMAKE_PCH_OUTPUT}
QMAKE_CXXFLAGS_PRECOMPILE = -x c++-header -c ${QMAKE_PCH_INPUT} -o ${QMAKE_PCH_OUTPUT}
QMAKE_CXXFLAGS_USE_PRECOMPILE = $$QMAKE_CFLAGS_USE_PRECOMPILE
1 change: 1 addition & 0 deletions doc/README.md
Expand Up @@ -44,6 +44,7 @@ The following are developer notes on how to build Syscoin Core on your native pl
- [FreeBSD Build Notes](build-freebsd.md)
- [OpenBSD Build Notes](build-openbsd.md)
- [NetBSD Build Notes](build-netbsd.md)
- [Android Build Notes](build-android.md)
- [Gitian Building Guide (External Link)](https://github.com/bitcoin-core/docs/blob/master/gitian-building.md)

Development
Expand Down
12 changes: 12 additions & 0 deletions doc/build-android.md
@@ -0,0 +1,12 @@
ANDROID BUILD NOTES
======================

This guide describes how to build and package the `syscoin-qt` GUI for Android on Linux and macOS.

## Preparation

You will need to get the Android NDK and build dependencies for Android as described in [depends/README.md](../depends/README.md).

## Building and packaging

After the depends are built configure with one of the resulting prefixes and run `make && make apk` in `src/qt`.
14 changes: 14 additions & 0 deletions src/Makefile.qt.include
Expand Up @@ -383,6 +383,20 @@ syscoin_qt_clean: FORCE

syscoin_qt : qt/syscoin-qt$(EXEEXT)

APK_LIB_DIR = qt/android/libs/$(ANDROID_ARCH)
QT_BASE_PATH = $(shell find ../depends/sources/ -maxdepth 1 -type f -regex ".*qtbase.*\.tar.xz")
QT_BASE_TLD = $(shell tar tf $(QT_BASE_PATH) --exclude='*/*')

syscoin_qt_apk: FORCE
mkdir -p $(APK_LIB_DIR)
cp $(dir $(CC))../sysroot/usr/lib/$(host_alias)/libc++_shared.so $(APK_LIB_DIR)
tar xf $(QT_BASE_PATH) -C qt/android/src/ $(QT_BASE_TLD)src/android/jar/src --strip-components=5
tar xf $(QT_BASE_PATH) -C qt/android/src/ $(QT_BASE_TLD)src/android/java/src --strip-components=5
tar xf $(QT_BASE_PATH) -C qt/android/res/ $(QT_BASE_TLD)src/android/java/res --strip-components=5
cp qt/syscoin-qt $(APK_LIB_DIR)/libsyscoin-qt.so
cd qt/android && gradle wrapper --gradle-version=6.6.1
cd qt/android && ./gradlew build

ui_%.h: %.ui
@test -f $(UIC)
@$(MKDIR_P) $(@D)
Expand Down
2 changes: 2 additions & 0 deletions src/qt/Makefile
Expand Up @@ -7,3 +7,5 @@ check: FORCE
$(MAKE) -C .. test_syscoin_qt_check
syscoin-qt syscoin-qt.exe: FORCE
$(MAKE) -C .. syscoin_qt
apk: FORCE
$(MAKE) -C .. syscoin_qt_apk
38 changes: 38 additions & 0 deletions src/qt/android/AndroidManifest.xml
@@ -0,0 +1,38 @@
<?xml version='1.0' encoding='utf-8'?>
<manifest package="org.syscoincore.qt" xmlns:android="http://schemas.android.com/apk/res/android" android:versionName="1.0" android:versionCode="1" android:installLocation="auto">
<uses-sdk android:targetSdkVersion="24"/>

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

<uses-feature android:glEsVersion="0x00020000" android:required="true" />

<supports-screens android:largeScreens="true" android:normalScreens="true" android:anyDensity="true" android:smallScreens="true"/>

<application android:hardwareAccelerated="true" android:name="org.qtproject.qt5.android.bindings.QtApplication" android:label="Syscoin Core">
<activity android:configChanges="orientation|uiMode|screenLayout|screenSize|smallestScreenSize|layoutDirection|locale|fontScale|keyboard|keyboardHidden|navigation|mcc|mnc|density"
android:name="org.syscoincore.qt.SyscoinQtActivity"
android:label="Syscoin Core"
android:icon="@drawable/syscoin"
android:screenOrientation="unspecified"
android:launchMode="singleTop">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>

<meta-data android:name="android.app.arguments" android:value="-testnet"/>
<meta-data android:name="android.app.lib_name" android:value="syscoin-qt"/>
<meta-data android:name="android.app.repository" android:value="default"/>
<meta-data android:name="android.app.bundle_local_qt_libs" android:value="1"/>
<meta-data android:name="android.app.use_local_qt_libs" android:value="1"/>
<meta-data android:name="android.app.libs_prefix" android:value="/data/local/tmp/qt/"/>
<meta-data android:name="android.app.system_libs_prefix" android:value="/system/lib/"/>
<meta-data android:name="android.app.background_running" android:value="true"/>
<meta-data android:name="android.app.auto_screen_scale_factor" android:value="true"/>
<meta-data android:name="android.app.extract_android_style" android:value="default"/>
</activity>

</application>
</manifest>
52 changes: 52 additions & 0 deletions src/qt/android/build.gradle
@@ -0,0 +1,52 @@
buildscript {
repositories {
google()
jcenter()
}

dependencies {
classpath 'com.android.tools.build:gradle:3.1.0'
}
}

repositories {
google()
jcenter()
}

apply plugin: 'com.android.application'

dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
}

android {
compileSdkVersion androidCompileSdkVersion.toInteger()

buildToolsVersion androidBuildToolsVersion

sourceSets {
main {
manifest.srcFile 'AndroidManifest.xml'
java.srcDirs = [qt5AndroidDir + '/src', 'src', 'java']
aidl.srcDirs = [qt5AndroidDir + '/src', 'src', 'aidl']
res.srcDirs = [qt5AndroidDir + '/res', 'res']
resources.srcDirs = ['src']
renderscript.srcDirs = ['src']
assets.srcDirs = ['assets']
jniLibs.srcDirs = ['libs']
}
}

lintOptions {
abortOnError false
}

dexOptions {
javaMaxHeapSize '4g'
}

defaultConfig {
minSdkVersion 24
}
}
4 changes: 4 additions & 0 deletions src/qt/android/gradle.properties
@@ -0,0 +1,4 @@
androidBuildToolsVersion=28.0.3
androidCompileSdkVersion=28
qt5AndroidDir=new File(".").absolutePath
org.gradle.jvmargs=-Xmx4608M
Binary file added src/qt/android/res/drawable-hdpi/syscoin.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/qt/android/res/drawable-ldpi/syscoin.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/qt/android/res/drawable-mdpi/syscoin.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/qt/android/res/drawable-xhdpi/syscoin.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/qt/android/res/drawable-xxhdpi/syscoin.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/qt/android/res/drawable-xxxhdpi/syscoin.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
29 changes: 29 additions & 0 deletions src/qt/android/src/org/bitcoincore/qt/BitcoinQtActivity.java
@@ -0,0 +1,29 @@
package org.syscoincore.qt;

import android.os.Bundle;
import android.system.ErrnoException;
import android.system.Os;

import org.qtproject.qt5.android.bindings.QtActivity;

import java.io.File;

public class SyscoinQtActivity extends QtActivity
{
@Override
public void onCreate(Bundle savedInstanceState)
{
final File syscoinDir = new File(getFilesDir().getAbsolutePath() + "/.syscoin");
if (!syscoinDir.exists()) {
syscoinDir.mkdir();
}

try {
Os.setenv("QT_QPA_PLATFORM", "android", true);
} catch (ErrnoException e) {
e.printStackTrace();
}

super.onCreate(savedInstanceState);
}
}
6 changes: 6 additions & 0 deletions src/qt/syscoin.cpp
Expand Up @@ -492,6 +492,12 @@ int GuiMain(int argc, char* argv[])
QApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);

#if defined(QT_QPA_PLATFORM_ANDROID)
QApplication::setAttribute(Qt::AA_DontUseNativeMenuBar);
QApplication::setAttribute(Qt::AA_DontCreateNativeWidgetSiblings);
QApplication::setAttribute(Qt::AA_DontUseNativeDialogs);
#endif

SyscoinApplication app;
QFontDatabase::addApplicationFont(":/fonts/monospace");

Expand Down

0 comments on commit 8a273cf

Please sign in to comment.