Browse Source

Add Qt5/QML building framework to contrib/android:

- update requirements file for building PyQt5
 - use separate .buildozer directories for qml and Kivy
 - add GUI and ARCH parameters to android/build.sh
patch-4
ThomasV 3 years ago
parent
commit
d91a4da557
  1. 2
      .gitignore
  2. 5
      contrib/android/Dockerfile
  3. 2
      contrib/android/Makefile
  4. 18
      contrib/android/build.sh
  5. 0
      contrib/android/buildozer_kivy.spec
  6. 253
      contrib/android/buildozer_qml.spec
  7. 43
      contrib/android/make_apk
  8. 2
      contrib/android/p4a_recipes/pyjnius/__init__.py
  9. 20
      contrib/deterministic-build/requirements-build-android.txt
  10. 4
      contrib/release.sh

2
.gitignore

@ -12,6 +12,8 @@ electrum/locale/
packages packages
env/ env/
.buildozer/ .buildozer/
.buildozer_kivy/
.buildozer_qml/
bin/ bin/
/app.fil /app.fil
.idea .idea

5
contrib/android/Dockerfile

@ -164,9 +164,10 @@ RUN cd /opt \
&& git clone https://github.com/kivy/python-for-android \ && git clone https://github.com/kivy/python-for-android \
&& cd python-for-android \ && cd python-for-android \
&& git remote add sombernight https://github.com/SomberNight/python-for-android \ && git remote add sombernight https://github.com/SomberNight/python-for-android \
&& git remote add accumulator https://github.com/accumulator/python-for-android \
&& git fetch --all \ && git fetch --all \
# commit: from branch sombernight/electrum_20210421b # commit: from branch accumulator/qt5-wip
&& git checkout "cdee188f0ef28ff8452207da409912da19e917ca^{commit}" \ && git checkout "ebbe8dcc271e36468666feb98f936d0a96936cf2^{commit}" \
&& python3 -m pip install --no-dependencies --user -e . && python3 -m pip install --no-dependencies --user -e .
# build env vars # build env vars

2
contrib/android/Makefile

@ -28,8 +28,8 @@ theming:
$(PYTHON) -m kivy.atlas ../../electrum/gui/kivy/theming/atlas/light 1024 ../../electrum/gui/kivy/theming/light/*.png $(PYTHON) -m kivy.atlas ../../electrum/gui/kivy/theming/atlas/light 1024 ../../electrum/gui/kivy/theming/light/*.png
prepare: prepare:
# running pre build setup # running pre build setup
@cp buildozer.spec ../../buildozer.spec
# copy electrum to main.py # copy electrum to main.py
@cp buildozer_$(ELEC_APK_GUI).spec ../../buildozer.spec
@cp ../../run_electrum ../../main.py @cp ../../run_electrum ../../main.py
@-if [ ! -d "../../.buildozer" ];then \ @-if [ ! -d "../../.buildozer" ];then \
cd ../..; buildozer android debug;\ cd ../..; buildozer android debug;\

18
contrib/android/build.sh

@ -14,6 +14,21 @@ DISTDIR="$PROJECT_ROOT/dist"
. "$CONTRIB"/build_tools_util.sh . "$CONTRIB"/build_tools_util.sh
# check arguments
if [[ -n "$3" \
&& ( "$1" == "kivy" || "$1" == "qml" ) \
&& ( "$2" == "all" || "$2" == "armeabi-v7a" || "$2" == "arm64-v8a" || "$2" == "x86" ) \
&& ( "$3" == "debug" || "$3" == "release" || "$3" == "release-unsigned" ) ]] ; then
info "arguments $*"
else
fail "usage: build.sh <kivy|qml> <arm64-v8a|armeabi-v7a|x86|all> <debug|release|release-unsigned>"
exit 1
fi
# create symlink
rm -f .buildozer
mkdir -p ".buildozer_$1"
ln -s ".buildozer_$1" .buildozer
DOCKER_BUILD_FLAGS="" DOCKER_BUILD_FLAGS=""
if [ ! -z "$ELECBUILD_NOCACHE" ] ; then if [ ! -z "$ELECBUILD_NOCACHE" ] ; then
@ -44,7 +59,8 @@ else
fi fi
DOCKER_RUN_FLAGS="" DOCKER_RUN_FLAGS=""
if [[ -n "$1" && "$1" == "release" ]] ; then
if [[ "$3" == "release" ]] ; then
info "'release' mode selected. mounting ~/.keystore inside container." info "'release' mode selected. mounting ~/.keystore inside container."
DOCKER_RUN_FLAGS="-v $HOME/.keystore:/home/user/.keystore" DOCKER_RUN_FLAGS="-v $HOME/.keystore:/home/user/.keystore"
fi fi

0
contrib/android/buildozer.spec → contrib/android/buildozer_kivy.spec

253
contrib/android/buildozer_qml.spec

@ -0,0 +1,253 @@
[app]
# (str) Title of your application
title = Electrum
# (str) Package name
package.name = Electrum
# (str) Package domain (needed for android/ios packaging)
package.domain = org.electrum
# (str) Source code where the main.py live
source.dir = .
# (list) Source files to include (let empty to include all the files)
source.include_exts = py,png,jpg,qml,qmltypes,ttf,txt,gif,pem,mo,vs,fs,json,csv,so
# (list) Source files to exclude (let empty to not exclude anything)
source.exclude_exts = spec
# (list) List of directory to exclude (let empty to not exclude anything)
source.exclude_dirs = bin, build, dist, contrib,
electrum/tests,
electrum/gui/qt,
electrum/gui/kivy,
packages/qdarkstyle,
packages/qtpy
# (list) List of exclusions using pattern matching
source.exclude_patterns = Makefile,setup*,
# not reproducible:
packages/aiohttp-*.dist-info/*
# (str) Application versioning (method 1)
version.regex = APK_VERSION = '(.*)'
version.filename = %(source.dir)s/electrum/version.py
# (str) Application versioning (method 2)
#version = 1.9.8
# (list) Application requirements
# note: versions and hashes are pinned in ./p4a_recipes/*
requirements =
hostpython3,
python3,
android,
openssl,
plyer,
libffi,
libsecp256k1,
cryptography,
pyqt5sip,
pyqt5
# (str) Presplash of the application
#presplash.filename = %(source.dir)s/gui/kivy/theming/splash.png
presplash.filename = %(source.dir)s/electrum/gui/icons/electrum_presplash.png
# (str) Icon of the application
icon.filename = %(source.dir)s/electrum/gui/icons/android_electrum_icon_legacy.png
icon.adaptive_foreground.filename = %(source.dir)s/electrum/gui/icons/android_electrum_icon_foreground.png
icon.adaptive_background.filename = %(source.dir)s/electrum/gui/icons/android_electrum_icon_background.png
# (str) Supported orientation (one of landscape, portrait or all)
orientation = portrait
# (bool) Indicate if the application should be fullscreen or not
fullscreen = False
#
# Android specific
#
# (list) Permissions
android.permissions = INTERNET, CAMERA, WRITE_EXTERNAL_STORAGE
# (int) Android API to use (targetSdkVersion AND compileSdkVersion)
# note: when changing, Dockerfile also needs to be changed to install corresponding build tools
android.api = 29
# (int) Minimum API required. You will need to set the android.ndk_api to be as low as this value.
android.minapi = 21
# (str) Android NDK version to use
android.ndk = 22b
# (int) Android NDK API to use (optional). This is the minimum API your app will support.
android.ndk_api = 21
# (bool) Use --private data storage (True) or --dir public storage (False)
android.private_storage = True
# (str) Android NDK directory (if empty, it will be automatically downloaded.)
android.ndk_path = /opt/android/android-ndk
# (str) Android SDK directory (if empty, it will be automatically downloaded.)
android.sdk_path = /opt/android/android-sdk
# (str) ANT directory (if empty, it will be automatically downloaded.)
android.ant_path = /opt/android/apache-ant
# (bool) If True, then skip trying to update the Android sdk
# This can be useful to avoid excess Internet downloads or save time
# when an update is due and you just want to test/build your package
# note(ghost43): probably needed for reproducibility. versions pinned in Dockerfile.
android.skip_update = True
# (bool) If True, then automatically accept SDK license
# agreements. This is intended for automation only. If set to False,
# the default, you will be shown the license when first running
# buildozer.
android.accept_sdk_license = True
# (str) Android entry point, default is ok for Kivy-based app
#android.entrypoint = org.renpy.android.PythonActivity
# (list) List of Java .jar files to add to the libs so that pyjnius can access
# their classes. Don't add jars that you do not need, since extra jars can slow
# down the build process. Allows wildcards matching, for example:
# OUYA-ODK/libs/*.jar
#android.add_jars = foo.jar,bar.jar,path/to/more/*.jar
#android.add_jars = lib/android/zbar.jar
android.add_jars = .buildozer/android/platform/*/build/libs_collections/Electrum/jar/*.jar
# (list) List of Java files to add to the android project (can be java or a
# directory containing the files)
android.add_src = electrum/gui/kivy/data/java-classes/
android.gradle_dependencies = me.dm7.barcodescanner:zxing:1.9.8
android.add_activities = org.electrum.qr.SimpleScannerActivity
# (str) python-for-android branch to use, if not master, useful to try
# not yet merged features.
#android.branch = master
# (str) OUYA Console category. Should be one of GAME or APP
# If you leave this blank, OUYA support will not be enabled
#android.ouya.category = GAME
# (str) Filename of OUYA Console icon. It must be a 732x412 png image.
#android.ouya.icon.filename = %(source.dir)s/data/ouya_icon.png
# (str) XML file to include as an intent filters in <activity> tag
android.manifest.intent_filters = contrib/android/bitcoin_intent.xml
# (str) launchMode to set for the main activity
android.manifest.launch_mode = singleTask
# (list) Android additionnal libraries to copy into libs/armeabi
#android.add_libs_armeabi = lib/android/*.so
# (bool) Indicate whether the screen should stay on
# Don't forget to add the WAKE_LOCK permission if you set this to True
#android.wakelock = False
# (str) The Android arch to build for, choices: armeabi-v7a, arm64-v8a, x86, x86_64
# note: can be overwritten by APP_ANDROID_ARCH env var
#android.arch = armeabi-v7a
# (list) Android application meta-data to set (key=value format)
#android.meta_data =
# (list) Android library project to add (will be added in the
# project.properties automatically.)
#android.library_references =
android.whitelist = lib-dynload/_csv.so
# (bool) enables Android auto backup feature (Android API >=23)
android.allow_backup = False
#
# Python for android (p4a) specific
#
# (str) python-for-android git clone directory (if empty, it will be automatically cloned from github)
p4a.source_dir = /opt/python-for-android
# (str) The directory in which python-for-android should look for your own build recipes (if any)
p4a.local_recipes = %(source.dir)s/contrib/android/p4a_recipes/
# (str) Filename to the hook for p4a
#p4a.hook =
# (str) Bootstrap to use for android builds
p4a.bootstrap = qt5
# (int) port number to specify an explicit --port= p4a argument (eg for bootstrap flask)
#p4a.port =
#
# iOS specific
#
# (str) Name of the certificate to use for signing the debug version
# Get a list of available identities: buildozer ios list_identities
#ios.codesign.debug = "iPhone Developer: <lastname> <firstname> (<hexstring>)"
# (str) Name of the certificate to use for signing the release version
#ios.codesign.release = %(ios.codesign.debug)s
[buildozer]
# (int) Log level (0 = error only, 1 = info, 2 = debug (with command output))
log_level = 1
# (str) Path to build output (i.e. .apk, .ipa) storage
bin_dir = ./dist
# -----------------------------------------------------------------------------
# List as sections
#
# You can define all the "list" as [section:key].
# Each line will be considered as a option to the list.
# Let's take [app] / source.exclude_patterns.
# Instead of doing:
#
# [app]
# source.exclude_patterns = license,data/audio/*.wav,data/images/original/*
#
# This can be translated into:
#
# [app:source.exclude_patterns]
# license
# data/audio/*.wav
# data/images/original/*
#
# -----------------------------------------------------------------------------
# Profiles
#
# You can extend section / key with a profile
# For example, you want to deploy a demo version of your application without
# HD content. You could first change the title to add "(demo)" in the name
# and extend the excluded directories to remove the HD content.
#
# [app@demo]
# title = My Application (demo)
#
# [app:source.exclude_patterns@demo]
# images/hd/*
#
# Then, invoke the command line with the "demo" profile:
#
# buildozer --profile demo android debug

43
contrib/android/make_apk

@ -10,6 +10,10 @@ LOCALE="$PROJECT_ROOT"/electrum/locale/
. "$CONTRIB"/build_tools_util.sh . "$CONTRIB"/build_tools_util.sh
# arguments have been checked in build.sh
export ELEC_APK_GUI=$1
if [ ! -d "$PACKAGES" ]; then if [ ! -d "$PACKAGES" ]; then
"$CONTRIB"/make_packages || fail "make_packages failed" "$CONTRIB"/make_packages || fail "make_packages failed"
fi fi
@ -37,28 +41,22 @@ info "preparing electrum-locale."
pushd "$CONTRIB_ANDROID" pushd "$CONTRIB_ANDROID"
info "apk building phase starts." info "apk building phase starts."
if [[ -n "$1" && "$1" == "release" ]] ; then
if [[ "$3" == "release" ]] ; then
# do release build, and sign the APKs. # do release build, and sign the APKs.
TARGET="release"
echo -n Keystore Password: echo -n Keystore Password:
read -s password read -s password
export P4A_RELEASE_KEYSTORE=~/.keystore export P4A_RELEASE_KEYSTORE=~/.keystore
export P4A_RELEASE_KEYSTORE_PASSWD=$password export P4A_RELEASE_KEYSTORE_PASSWD=$password
export P4A_RELEASE_KEYALIAS_PASSWD=$password export P4A_RELEASE_KEYALIAS_PASSWD=$password
export P4A_RELEASE_KEYALIAS=electrum export P4A_RELEASE_KEYALIAS=electrum
# build two apks elif [[ "$3" == "release-unsigned" ]] ; then
export APP_ANDROID_ARCH=armeabi-v7a
make release
export APP_ANDROID_ARCH=arm64-v8a
make release
elif [[ -n "$1" && "$1" == "release-unsigned" ]] ; then
# do release build, but do not sign the APKs. # do release build, but do not sign the APKs.
# build two apks TARGET="release"
export APP_ANDROID_ARCH=armeabi-v7a elif [[ "$3" == "debug" ]] ; then
make release
export APP_ANDROID_ARCH=arm64-v8a
make release
else
# do debug build; the default. # do debug build; the default.
TARGET="apk"
export P4A_DEBUG_KEYSTORE="$CONTRIB_ANDROID"/android_debug.keystore export P4A_DEBUG_KEYSTORE="$CONTRIB_ANDROID"/android_debug.keystore
export P4A_DEBUG_KEYSTORE_PASSWD=unsafepassword export P4A_DEBUG_KEYSTORE_PASSWD=unsafepassword
export P4A_DEBUG_KEYALIAS_PASSWD=unsafepassword export P4A_DEBUG_KEYALIAS_PASSWD=unsafepassword
@ -72,11 +70,22 @@ else
-keypass "$P4A_DEBUG_KEYALIAS_PASSWD" -keypass "$P4A_DEBUG_KEYALIAS_PASSWD"
fi fi
export ELEC_APK_USE_CURRENT_TIME=1 export ELEC_APK_USE_CURRENT_TIME=1
# only build one apk for debug build, for faster testing iterations else
fail "unknown build type"
fi
if [[ "$2" == "all" ]] ; then
# build all apks
export APP_ANDROID_ARCH=armeabi-v7a
make $TARGET
export APP_ANDROID_ARCH=arm64-v8a export APP_ANDROID_ARCH=arm64-v8a
make apk make $TARGET
# export APP_ANDROID_ARCH=armeabi-v7a #export APP_ANDROID_ARCH=x86
# make apk #make $TARGET
else
export APP_ANDROID_ARCH=$2
make $TARGET
fi fi
popd popd

2
contrib/android/p4a_recipes/pyjnius/__init__.py

@ -7,7 +7,7 @@ util = load_source('util', os.path.join(os.path.dirname(os.path.dirname(__file__
assert PyjniusRecipe._version == "1.3.0" assert PyjniusRecipe._version == "1.3.0"
assert PyjniusRecipe.depends == [('genericndkbuild', 'sdl2'), 'six', 'python3'] assert PyjniusRecipe.depends == [('genericndkbuild', 'sdl2', 'qt5'), 'six', 'python3']
assert PyjniusRecipe.python_depends == [] assert PyjniusRecipe.python_depends == []

20
contrib/deterministic-build/requirements-build-android.txt

@ -164,4 +164,22 @@ zipp==3.7.0 \
--hash=sha256:b47250dd24f92b7dd6a0a8fc5244da14608f3ca90a5efcd37a3b1642fac9a375 --hash=sha256:b47250dd24f92b7dd6a0a8fc5244da14608f3ca90a5efcd37a3b1642fac9a375
pathlib2==2.3.7.post1 \ pathlib2==2.3.7.post1 \
--hash=sha256:5266a0fd000452f1b3467d782f079a4343c63aaa119221fbdc4e39577489ca5b \ --hash=sha256:5266a0fd000452f1b3467d782f079a4343c63aaa119221fbdc4e39577489ca5b \
--hash=sha256:9fe0edad898b83c0c3e199c842b27ed216645d2e177757b2dd67384d4113c641 --hash=sha256:9fe0edad898b83c0c3e199c842b27ed216645d2e177757b2dd67384d4113c641 \
typing-extensions==3.7.4.3 \
--hash=sha256:7cb407020f00f7bfc3cb3e7881628838e69d8f3fcab2f64742a5e76b2f841918 \
--hash=sha256:99d4073b617d30288f569d3f13d2bd7548c3a7e4c8de87db09a9d29bb3a4a60c \
--hash=sha256:dafc7639cde7f1b6e1acc0f457842a83e722ccca8eef5270af2d74792619a89f
sip==6.4.0 \
--hash=sha256:0a1a2db03ef71372744d00a671406b0fabf920da53192cdd4a8fa9ddb76888bd \
--hash=sha256:2ff8632ace4f274fe37ce3e09967877b672490ada33c034addca6d63dc534310 \
--hash=sha256:42ec368520b8da4a0987218510b1b520b4981e4405086c1be384733affc2bcb0 \
--hash=sha256:87539b534d730aaabde7396bd2edb7c5b86093ca2500eeaa617d588150b7fda9
pyparsing==3.0.6 \
--hash=sha256:04ff808a5b90911829c55c4e26f75fa5ca8a2f5f36aa3a51f68e27033341d3e4 \
--hash=sha256:d9bdec0013ef1eb5a84ab39a3b3868911598afa494f5faa038647101504e2b81
PyQt-builder==1.12.2 \
--hash=sha256:48f754394d235307201ec2b5355934858741201af09433ff543ca40ae57b7865 \
--hash=sha256:f62bb688d70e0afd88c413a8d994bda824e6cebd12b612902d1945c5a67edcd7
packaging==21.3 \
--hash=sha256:dd47c42927d89ab911e606518907cc2d3a1f38bbd026385970643f9c5b8ecfeb \
--hash=sha256:ef103e05f519cdc783ae24ea4e2e0f508a9c99b2d4969652eed6a2e1ea5bd522

4
contrib/release.sh

@ -125,9 +125,9 @@ if test -f "dist/$apk1"; then
info "file exists: $apk1" info "file exists: $apk1"
else else
if [ ! -z "$RELEASEMANAGER" ] ; then if [ ! -z "$RELEASEMANAGER" ] ; then
./contrib/android/build.sh release ./contrib/android/build.sh kivy all release
else else
./contrib/android/build.sh release-unsigned ./contrib/android/build.sh kivy all release-unsigned
mv "$apk1_unsigned" "$apk1" mv "$apk1_unsigned" "$apk1"
mv "$apk2_unsigned" "$apk2" mv "$apk2_unsigned" "$apk2"
fi fi

Loading…
Cancel
Save