Skip to content

Commit 23b1560

Browse files
committed
Merge #17227: Qt: Add Android packaging support
246774e depends: fix Qt precompiled headers bug (Igor Cota) 8e7ad41 depends: disable Qt Vulkan support on Android (Igor Cota) ba46ada CI: add Android APK build to cirrus (Igor Cota) 7563720 CI: add Android APK build script (Igor Cota) ebfb10c Qt: add Android packaging support (Igor Cota) Pull request description: ![bitcoin-qt](https://user-images.githubusercontent.com/762502/67396157-62f3d000-f5a7-11e9-8a6f-9425823fcd6c.gif) This PR is the third and final piece of the basic Android support puzzle - it depends on bitcoin/bitcoin#16110 and is related to bitcoin/bitcoin#16883. It introduces an `android` directory under `qt` and a simple way to build an Android package of `bitcoin-qt`: 1. Build depends for Android as described in the [README](https://github.com/bitcoin/bitcoin/blob/master/depends/README.md) 2. Configure with one of the resulting prefixes 3. Run `make && make apk` in `src/qt` The resulting APK files will be in `android/build/outputs/apk`. You can install them manually or with [adb](https://developer.android.com/studio/command-line/adb). One can also open the `android` directory in Android Studio for that integrated development and debugging experience. `BitcoinQtActivity` is your starting point. Under the hood makefile `apk` target: 1. Renames the `bitcoin-qt` binary to `libbitcoin-qt.so` and copies it over to a folder under `android/libs` depending on which prefix and corresponding [ABI](https://developer.android.com/ndk/guides/abis.html#sa) `bitcoin-qt` was built for 2. Takes `libc++_shared.so` from the Android NDK and puts in the same place. It [must be included](https://developer.android.com/ndk/guides/cpp-support) in the APK 3. Extracts Qt for Android Java support files from the `qtbase` archive in `depends/sources` to `android/src` There is also just a tiny bit of `ifdef`'d code to make the Qt Widgets menus usable. It's not pretty but it works and is a stepping stone towards bitcoin/bitcoin#16883. ACKs for top commit: MarcoFalke: cr ACK 246774e laanwj: Code review ACK 246774e Tree-SHA512: ba30a746576a167545223c35a51ae60bb0838818779fc152c210f5af1413961b2a6ab6af520ff92cbc8dcd5dcb663e81ca960f021218430c1f76397ed4cead6c
2 parents b1281b5 + 246774e commit 23b1560

File tree

22 files changed

+234
-1
lines changed

22 files changed

+234
-1
lines changed

.cirrus.yml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,3 +180,11 @@ task:
180180
CI_USE_APT_INSTALL: "no"
181181
PACKAGE_MANAGER_INSTALL: "echo" # Nothing to do
182182
FILE_ENV: "./ci/test/00_setup_env_mac_host.sh"
183+
184+
task:
185+
name: 'ARM64 Android APK [bionic]'
186+
<< : *GLOBAL_TASK_TEMPLATE
187+
container:
188+
image: ubuntu:bionic
189+
env:
190+
FILE_ENV: "./ci/test/00_setup_env_android.sh"

ci/test/00_setup_env_android.sh

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
#!/usr/bin/env bash
2+
#
3+
# Copyright (c) 2019-2020 The Bitcoin Core developers
4+
# Distributed under the MIT software license, see the accompanying
5+
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
6+
7+
export LC_ALL=C.UTF-8
8+
9+
export CONTAINER_NAME=ci_android
10+
export PACKAGES="clang llvm unzip openjdk-8-jdk gradle"
11+
12+
export ANDROID_API_LEVEL=28
13+
export ANDROID_BUILD_TOOLS_VERSION=28.0.3
14+
export ANDROID_NDK_VERSION=21.1.6352462
15+
export ANDROID_TOOLS_URL=https://dl.google.com/android/repository/commandlinetools-linux-6609375_latest.zip
16+
17+
export BITCOIN_CONFIG="--disable-ccache"

ci/test/05_before_script.sh

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,20 @@ if [ -n "$XCODE_VERSION" ] && [ ! -f "$OSX_SDK_PATH" ]; then
2222
DOCKER_EXEC curl --location --fail "${SDK_URL}/${OSX_SDK_BASENAME}" -o "$OSX_SDK_PATH"
2323
fi
2424

25+
if [ -n "$ANDROID_TOOLS_URL" ]; then
26+
ANDROID_TOOLS_PATH=$DEPENDS_DIR/sdk-sources/android-tools.zip
27+
ANDROID_HOME="$DEPENDS_DIR"/SDKs/android
28+
ANDROID_NDK_HOME=${ANDROID_HOME}/ndk/${ANDROID_NDK_VERSION}
29+
30+
DOCKER_EXEC curl --location --fail "${ANDROID_TOOLS_URL}" -o "$ANDROID_TOOLS_PATH"
31+
DOCKER_EXEC mkdir -p "${ANDROID_HOME}/cmdline-tools"
32+
DOCKER_EXEC unzip -o "$ANDROID_TOOLS_PATH" -d "${ANDROID_HOME}/cmdline-tools"
33+
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}\""
34+
35+
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"
36+
DOCKER_EXEC "$MAKE_COMMAND" HOST=aarch64-linux-android
37+
fi
38+
2539
if [[ ${USE_MEMORY_SANITIZER} == "true" ]]; then
2640
# Use BDB compiled using install_db4.sh script to work around linking issue when using BDB
2741
# from depends. See https://github.com/bitcoin/bitcoin/pull/18288#discussion_r433189350 for

ci/test/06_script_a.sh

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,14 @@
66

77
export LC_ALL=C.UTF-8
88

9+
if [ -n "$ANDROID_TOOLS_URL" ]; then
10+
DOCKER_EXEC make distclean || true
11+
DOCKER_EXEC ./autogen.sh
12+
DOCKER_EXEC ./configure $BITCOIN_CONFIG --prefix=$DEPENDS_DIR/aarch64-linux-android || ( (DOCKER_EXEC cat config.log) && false)
13+
DOCKER_EXEC "cd src/qt && make $MAKEJOBS && ANDROID_HOME=${ANDROID_HOME} ANDROID_NDK_HOME=${ANDROID_NDK_HOME} make apk"
14+
exit 0
15+
fi
16+
917
BITCOIN_CONFIG_ALL="--enable-suppress-external-warnings --disable-dependency-tracking --prefix=$DEPENDS_DIR/$HOST --bindir=$BASE_OUTDIR/bin --libdir=$BASE_OUTDIR/lib"
1018
if [ -z "$NO_WERROR" ]; then
1119
BITCOIN_CONFIG_ALL="${BITCOIN_CONFIG_ALL} --enable-werror"

configure.ac

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -734,6 +734,21 @@ case $host in
734734
*android*)
735735
dnl make sure android stays above linux for hosts like *linux-android*
736736
TARGET_OS=android
737+
case $host in
738+
*x86_64*)
739+
ANDROID_ARCH=x86_64
740+
;;
741+
*aarch64*)
742+
ANDROID_ARCH=arm64-v8a
743+
;;
744+
*armv7a*)
745+
ANDROID_ARCH=armeabi-v7a
746+
;;
747+
*i686*)
748+
ANDROID_ARCH=i686
749+
;;
750+
*) AC_MSG_ERROR("Could not determine Android arch") ;;
751+
esac
737752
;;
738753
*linux*)
739754
TARGET_OS=linux
@@ -1849,6 +1864,7 @@ AC_SUBST(HAVE_BUILTIN_PREFETCH)
18491864
AC_SUBST(HAVE_MM_PREFETCH)
18501865
AC_SUBST(HAVE_STRONG_GETAUXVAL)
18511866
AC_SUBST(HAVE_WEAK_GETAUXVAL)
1867+
AC_SUBST(ANDROID_ARCH)
18521868
AC_CONFIG_FILES([Makefile src/Makefile doc/man/Makefile share/setup.nsi share/qt/Info.plist test/config.ini])
18531869
AC_CONFIG_FILES([contrib/devtools/split-debug.sh],[chmod +x contrib/devtools/split-debug.sh])
18541870
AM_COND_IF([HAVE_DOXYGEN], [AC_CONFIG_FILES([doc/Doxyfile])])

depends/packages/qt.mk

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ $(package)_qt_libs=corelib network widgets gui plugins testlib
99
$(package)_patches=fix_qt_pkgconfig.patch mac-qmake.conf fix_no_printer.patch no-xlib.patch
1010
$(package)_patches+= fix_android_qmake_conf.patch fix_android_jni_static.patch dont_hardcode_pwd.patch
1111
$(package)_patches+= drop_lrelease_dependency.patch no_sdk_version_check.patch
12-
$(package)_patches+= fix_qpainter_non_determinism.patch fix_lib_paths.patch
12+
$(package)_patches+= fix_qpainter_non_determinism.patch fix_lib_paths.patch fix_android_pch.patch
1313

1414
$(package)_qttranslations_file_name=qttranslations-$($(package)_suffix)
1515
$(package)_qttranslations_sha256_hash=e1de58ed108b7e0a138815ea60fd46a2c4e1fc31396a707e5630e92de79c53de
@@ -165,6 +165,7 @@ $(package)_config_opts_android += -no-fontconfig
165165
$(package)_config_opts_android += -L $(host_prefix)/lib
166166
$(package)_config_opts_android += -I $(host_prefix)/include
167167
$(package)_config_opts_android += -pch
168+
$(package)_config_opts_android += -no-feature-vulkan
168169

169170
$(package)_config_opts_aarch64_android += -android-arch arm64-v8a
170171
$(package)_config_opts_armv7a_android += -android-arch armeabi-v7a
@@ -224,6 +225,7 @@ define $(package)_preprocess_cmds
224225
patch -p1 -i $($(package)_patch_dir)/fix_no_printer.patch && \
225226
patch -p1 -i $($(package)_patch_dir)/fix_android_qmake_conf.patch && \
226227
patch -p1 -i $($(package)_patch_dir)/fix_android_jni_static.patch && \
228+
patch -p1 -i $($(package)_patch_dir)/fix_android_pch.patch && \
227229
patch -p1 -i $($(package)_patch_dir)/no-xlib.patch && \
228230
patch -p1 -i $($(package)_patch_dir)/fix_qpainter_non_determinism.patch &&\
229231
patch -p1 -i $($(package)_patch_dir)/no_sdk_version_check.patch && \
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
--- old/qtbase/mkspecs/common/android-base-head.conf
2+
+++ new/qtbase/mkspecs/common/android-base-head.conf
3+
@@ -73,6 +73,6 @@ CROSS_COMPILE = $$NDK_TOOLCHAIN_PATH/bin/$$NDK_TOOLS_PREFIX-
4+
QMAKE_PCH_OUTPUT_EXT = .gch
5+
6+
QMAKE_CFLAGS_PRECOMPILE = -x c-header -c ${QMAKE_PCH_INPUT} -o ${QMAKE_PCH_OUTPUT}
7+
-QMAKE_CFLAGS_USE_PRECOMPILE = -include ${QMAKE_PCH_OUTPUT_BASE}
8+
+QMAKE_CFLAGS_USE_PRECOMPILE = -include-pch ${QMAKE_PCH_OUTPUT}
9+
QMAKE_CXXFLAGS_PRECOMPILE = -x c++-header -c ${QMAKE_PCH_INPUT} -o ${QMAKE_PCH_OUTPUT}
10+
QMAKE_CXXFLAGS_USE_PRECOMPILE = $$QMAKE_CFLAGS_USE_PRECOMPILE

doc/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ The following are developer notes on how to build Bitcoin Core on your native pl
4444
- [FreeBSD Build Notes](build-freebsd.md)
4545
- [OpenBSD Build Notes](build-openbsd.md)
4646
- [NetBSD Build Notes](build-netbsd.md)
47+
- [Android Build Notes](build-android.md)
4748
- [Gitian Building Guide (External Link)](https://github.com/bitcoin-core/docs/blob/master/gitian-building.md)
4849

4950
Development

doc/build-android.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
ANDROID BUILD NOTES
2+
======================
3+
4+
This guide describes how to build and package the `bitcoin-qt` GUI for Android on Linux and macOS.
5+
6+
## Preparation
7+
8+
You will need to get the Android NDK and build dependencies for Android as described in [depends/README.md](../depends/README.md).
9+
10+
## Building and packaging
11+
12+
After the depends are built configure with one of the resulting prefixes and run `make && make apk` in `src/qt`.

src/Makefile.qt.include

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -378,6 +378,20 @@ bitcoin_qt_clean: FORCE
378378

379379
bitcoin_qt : qt/bitcoin-qt$(EXEEXT)
380380

381+
APK_LIB_DIR = qt/android/libs/$(ANDROID_ARCH)
382+
QT_BASE_PATH = $(shell find ../depends/sources/ -maxdepth 1 -type f -regex ".*qtbase.*\.tar.xz")
383+
QT_BASE_TLD = $(shell tar tf $(QT_BASE_PATH) --exclude='*/*')
384+
385+
bitcoin_qt_apk: FORCE
386+
mkdir -p $(APK_LIB_DIR)
387+
cp $(dir $(CC))../sysroot/usr/lib/$(host_alias)/libc++_shared.so $(APK_LIB_DIR)
388+
tar xf $(QT_BASE_PATH) -C qt/android/src/ $(QT_BASE_TLD)src/android/jar/src --strip-components=5
389+
tar xf $(QT_BASE_PATH) -C qt/android/src/ $(QT_BASE_TLD)src/android/java/src --strip-components=5
390+
tar xf $(QT_BASE_PATH) -C qt/android/res/ $(QT_BASE_TLD)src/android/java/res --strip-components=5
391+
cp qt/bitcoin-qt $(APK_LIB_DIR)/libbitcoin-qt.so
392+
cd qt/android && gradle wrapper --gradle-version=6.6.1
393+
cd qt/android && ./gradlew build
394+
381395
ui_%.h: %.ui
382396
@test -f $(UIC)
383397
@$(MKDIR_P) $(@D)

0 commit comments

Comments
 (0)