diff --git a/contrib/android/buildozer.spec b/contrib/android/buildozer.spec index 16bee6519..3a31468ff 100644 --- a/contrib/android/buildozer.spec +++ b/contrib/android/buildozer.spec @@ -36,14 +36,14 @@ version.filename = %(source.dir)s/electrum/version.py #version = 1.9.8 # (list) Application requirements +# note: versions and hashes are pinned in ./p4a_recipes/* requirements = - hostpython3==3.8.8, - python3==3.8.8, + hostpython3, + python3, android, openssl, plyer, - # kivy master 2020-12-10 (2.0.0 plus a few bugfixes) - kivy==2debbc3b1484b14824112986cb03b1072a60fbfc, + kivy, libffi, libsecp256k1, cryptography @@ -162,7 +162,7 @@ android.allow_backup = False 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 = +p4a.local_recipes = %(source.dir)s/contrib/android/p4a_recipes/ # (str) Filename to the hook for p4a #p4a.hook = diff --git a/contrib/android/p4a_recipes/README.md b/contrib/android/p4a_recipes/README.md new file mode 100644 index 000000000..3c4067909 --- /dev/null +++ b/contrib/android/p4a_recipes/README.md @@ -0,0 +1,10 @@ +python-for-android local recipes +-------------------------------- + +These folders are recipes (build scripts) for most of our direct and transitive +dependencies for the Android app. python-for-android has recipes built-in for +many packages but it also allows users to specify their "local" recipes. +Local recipes have precedence over the built-in recipes. + +The local recipes we have here are mostly just used to pin down specific +versions and hashes for reproducibility. The hashes are updated manually. diff --git a/contrib/android/p4a_recipes/certifi/__init__.py b/contrib/android/p4a_recipes/certifi/__init__.py new file mode 100644 index 000000000..94b7d4ce4 --- /dev/null +++ b/contrib/android/p4a_recipes/certifi/__init__.py @@ -0,0 +1,15 @@ +from pythonforandroid.recipe import PythonRecipe + + +assert PythonRecipe.depends == ['python3'] +assert PythonRecipe.python_depends == [] + + +class CertifiRecipePinned(PythonRecipe): + version = "2020.12.5" + sha512sum = "3425d98f19025e70d885458629071c8531271d93d1461fadea6afbaafc763881a42b3c05be391a938d84a0d1ab729c3ac5df4f3328e8ef63a7b56ead1445bddd" + url = "https://pypi.python.org/packages/source/c/certifi/certifi-{version}.tar.gz" + depends = ["setuptools"] + + +recipe = CertifiRecipePinned() diff --git a/contrib/android/p4a_recipes/cffi/__init__.py b/contrib/android/p4a_recipes/cffi/__init__.py new file mode 100644 index 000000000..a32b1c2e8 --- /dev/null +++ b/contrib/android/p4a_recipes/cffi/__init__.py @@ -0,0 +1,18 @@ +import os + +from pythonforandroid.recipes.cffi import CffiRecipe +from pythonforandroid.util import load_source + +util = load_source('util', os.path.join(os.path.dirname(os.path.dirname(__file__)), 'util.py')) + + +assert CffiRecipe._version == "1.13.2" +assert CffiRecipe.depends == ['setuptools', 'pycparser', 'libffi', 'python3'] +assert CffiRecipe.python_depends == [] + + +class CffiRecipePinned(util.InheritedRecipeMixin, CffiRecipe): + sha512sum = "2c57d9c06c39e95498a54408dc39940427190f3c03e1b8f1a3584140db08a5775dd12e6e67b03093429c130af579d01519b0fc868b99ba7a530068ed22d38522" + + +recipe = CffiRecipePinned() diff --git a/contrib/android/p4a_recipes/cryptography/__init__.py b/contrib/android/p4a_recipes/cryptography/__init__.py new file mode 100644 index 000000000..5c6bd1bf2 --- /dev/null +++ b/contrib/android/p4a_recipes/cryptography/__init__.py @@ -0,0 +1,13 @@ +from pythonforandroid.recipes.cryptography import CryptographyRecipe + + +assert CryptographyRecipe._version == "2.8" +assert CryptographyRecipe.depends == ['openssl', 'six', 'setuptools', 'cffi', 'python3'] +assert CryptographyRecipe.python_depends == [] + + +class CryptographyRecipePinned(CryptographyRecipe): + sha512sum = "000816a5513691bfbb01c5c65d96fb3567a5ff25300da4b485e716b6d4dc789aec05ed0fe65df9c5e3e60127aa9110f04e646407db5b512f88882b0659f7123f" + + +recipe = CryptographyRecipePinned() diff --git a/contrib/android/p4a_recipes/hostpython3/__init__.py b/contrib/android/p4a_recipes/hostpython3/__init__.py new file mode 100644 index 000000000..6c9cf5a17 --- /dev/null +++ b/contrib/android/p4a_recipes/hostpython3/__init__.py @@ -0,0 +1,18 @@ +import os + +from pythonforandroid.recipes.hostpython3 import HostPython3Recipe +from pythonforandroid.util import load_source + +util = load_source('util', os.path.join(os.path.dirname(os.path.dirname(__file__)), 'util.py')) + + +assert HostPython3Recipe.depends == [] +assert HostPython3Recipe.python_depends == [] + + +class HostPython3RecipePinned(util.InheritedRecipeMixin, HostPython3Recipe): + version = "3.8.8" + sha512sum = "1c6742cdc92ba6d3c03c63fd025bc348462517a503343685a42e22838aedc94ab2e438f1d1623b91ca1be5f39f327d76385d66b785ff93f0f3737b9870e9a003" + + +recipe = HostPython3RecipePinned() diff --git a/contrib/android/p4a_recipes/kivy/__init__.py b/contrib/android/p4a_recipes/kivy/__init__.py new file mode 100644 index 000000000..2f8fb2670 --- /dev/null +++ b/contrib/android/p4a_recipes/kivy/__init__.py @@ -0,0 +1,18 @@ +from pythonforandroid.recipes.kivy import KivyRecipe + + +assert KivyRecipe.depends == ['sdl2', 'pyjnius', 'setuptools', 'python3'] +assert KivyRecipe.python_depends == ['certifi'] + + +class KivyRecipePinned(KivyRecipe): + # kivy master 2020-12-10 (2.0.0 plus a few bugfixes) + version = "2debbc3b1484b14824112986cb03b1072a60fbfc" + sha512sum = "6cabb77860e63059ab4b0663b87f6396fa9133839b42db754628fc9a55f10b8d759466110e0763fd8dac40a49a03af276cb93b05076471d12db796e679f33d1d" + + # mv "python_depends" into "depends" to ensure we can control what versions get installed + depends = [*KivyRecipe.depends, *KivyRecipe.python_depends] + python_depends = [] + + +recipe = KivyRecipePinned() diff --git a/contrib/android/p4a_recipes/libffi/__init__.py b/contrib/android/p4a_recipes/libffi/__init__.py new file mode 100644 index 000000000..4867cc031 --- /dev/null +++ b/contrib/android/p4a_recipes/libffi/__init__.py @@ -0,0 +1,18 @@ +import os + +from pythonforandroid.recipes.libffi import LibffiRecipe +from pythonforandroid.util import load_source + +util = load_source('util', os.path.join(os.path.dirname(os.path.dirname(__file__)), 'util.py')) + + +assert LibffiRecipe._version == "v3.3" +assert LibffiRecipe.depends == [] +assert LibffiRecipe.python_depends == [] + + +class LibffiRecipePinned(util.InheritedRecipeMixin, LibffiRecipe): + sha512sum = "62798fb31ba65fa2a0e1f71dd3daca30edcf745dc562c6f8e7126e54db92572cc63f5aa36d927dd08375bb6f38a2380ebe6c5735f35990681878fc78fc9dbc83" + + +recipe = LibffiRecipePinned() diff --git a/contrib/android/p4a_recipes/libsecp256k1/__init__.py b/contrib/android/p4a_recipes/libsecp256k1/__init__.py new file mode 100644 index 000000000..df703f177 --- /dev/null +++ b/contrib/android/p4a_recipes/libsecp256k1/__init__.py @@ -0,0 +1,14 @@ +from pythonforandroid.recipes.libsecp256k1 import LibSecp256k1Recipe + + +assert LibSecp256k1Recipe.depends == [] +assert LibSecp256k1Recipe.python_depends == [] + + +class LibSecp256k1RecipePinned(LibSecp256k1Recipe): + version = "dbd41db16a0e91b2566820898a3ab2d7dad4fe00" + url = "https://github.com/bitcoin-core/secp256k1/archive/{version}.zip" + sha512sum = "9012586149fb952309f0a1eb9f41dcd668f839eb38bfa9e942b53b1974b793dfe7616879766837f3d98d1523c826a49ead966bca35aee11d734c81a2f6fd9bf9" + + +recipe = LibSecp256k1RecipePinned() diff --git a/contrib/android/p4a_recipes/openssl/__init__.py b/contrib/android/p4a_recipes/openssl/__init__.py new file mode 100644 index 000000000..17e29d6dc --- /dev/null +++ b/contrib/android/p4a_recipes/openssl/__init__.py @@ -0,0 +1,18 @@ +import os + +from pythonforandroid.recipes.openssl import OpenSSLRecipe +from pythonforandroid.util import load_source + +util = load_source('util', os.path.join(os.path.dirname(os.path.dirname(__file__)), 'util.py')) + + +assert OpenSSLRecipe.url_version == "1.1.1k" +assert OpenSSLRecipe.depends == [] +assert OpenSSLRecipe.python_depends == [] + + +class OpenSSLRecipePinned(util.InheritedRecipeMixin, OpenSSLRecipe): + sha512sum = "73cd042d4056585e5a9dd7ab68e7c7310a3a4c783eafa07ab0b560e7462b924e4376436a6d38a155c687f6942a881cfc0c1b9394afcde1d8c46bf396e7d51121" + + +recipe = OpenSSLRecipePinned() diff --git a/contrib/android/p4a_recipes/plyer/__init__.py b/contrib/android/p4a_recipes/plyer/__init__.py new file mode 100644 index 000000000..731dc22e8 --- /dev/null +++ b/contrib/android/p4a_recipes/plyer/__init__.py @@ -0,0 +1,15 @@ +from pythonforandroid.recipe import PythonRecipe + + +assert PythonRecipe.depends == ['python3'] +assert PythonRecipe.python_depends == [] + + +class PlyerRecipePinned(PythonRecipe): + version = "2.0.0" + sha512sum = "8088eeb41aac753435ff5be9835be74d57a55cf557ad76cbad8026352647e554571fae6172754e39882ea7ef07cc1e97fac16556a4426456de99daebe5cd01cf" + url = "https://pypi.python.org/packages/source/p/plyer/plyer-{version}.tar.gz" + depends = ["setuptools"] + + +recipe = PlyerRecipePinned() diff --git a/contrib/android/p4a_recipes/pycparser/__init__.py b/contrib/android/p4a_recipes/pycparser/__init__.py new file mode 100644 index 000000000..aebfd988f --- /dev/null +++ b/contrib/android/p4a_recipes/pycparser/__init__.py @@ -0,0 +1,13 @@ +from pythonforandroid.recipes.pycparser import PycparserRecipe + + +assert PycparserRecipe._version == "2.14" +assert PycparserRecipe.depends == ['setuptools', 'python3'] +assert PycparserRecipe.python_depends == [] + + +class PycparserRecipePinned(PycparserRecipe): + sha512sum = "d5b9ab434a8944898ac23a4f51189db77b02b993bf3e3ca018852b117fc0eb43e460b156beaa5c1d631ad71c81e1649113e9fff7e33506b1e7d4de24d8b464c6" + + +recipe = PycparserRecipePinned() diff --git a/contrib/android/p4a_recipes/pyjnius/__init__.py b/contrib/android/p4a_recipes/pyjnius/__init__.py new file mode 100644 index 000000000..2321b14b3 --- /dev/null +++ b/contrib/android/p4a_recipes/pyjnius/__init__.py @@ -0,0 +1,18 @@ +import os + +from pythonforandroid.recipes.pyjnius import PyjniusRecipe +from pythonforandroid.util import load_source + +util = load_source('util', os.path.join(os.path.dirname(os.path.dirname(__file__)), 'util.py')) + + +assert PyjniusRecipe._version == "1.3.0" +assert PyjniusRecipe.depends == [('genericndkbuild', 'sdl2'), 'six', 'python3'] +assert PyjniusRecipe.python_depends == [] + + +class PyjniusRecipePinned(util.InheritedRecipeMixin, PyjniusRecipe): + sha512sum = "5a3475afcda5afbef6e1a67bab508e3c24bd564efda5ac38ae7669d39b4bfdbfaaa83f435f26d39b3d849d3a167a9c136c9ac6b2bfcc0bda09ef1c00aa66cf25" + + +recipe = PyjniusRecipePinned() diff --git a/contrib/android/p4a_recipes/python3/__init__.py b/contrib/android/p4a_recipes/python3/__init__.py new file mode 100644 index 000000000..7611d5bf1 --- /dev/null +++ b/contrib/android/p4a_recipes/python3/__init__.py @@ -0,0 +1,18 @@ +import os + +from pythonforandroid.recipes.python3 import Python3Recipe +from pythonforandroid.util import load_source + +util = load_source('util', os.path.join(os.path.dirname(os.path.dirname(__file__)), 'util.py')) + + +assert Python3Recipe.depends == ['hostpython3', 'sqlite3', 'openssl', 'libffi'] +assert Python3Recipe.python_depends == [] + + +class Python3RecipePinned(util.InheritedRecipeMixin, Python3Recipe): + version = "3.8.8" + sha512sum = "1c6742cdc92ba6d3c03c63fd025bc348462517a503343685a42e22838aedc94ab2e438f1d1623b91ca1be5f39f327d76385d66b785ff93f0f3737b9870e9a003" + + +recipe = Python3RecipePinned() diff --git a/contrib/android/p4a_recipes/sdl2/__init__.py b/contrib/android/p4a_recipes/sdl2/__init__.py new file mode 100644 index 000000000..07dc059b8 --- /dev/null +++ b/contrib/android/p4a_recipes/sdl2/__init__.py @@ -0,0 +1,19 @@ +import os + +from pythonforandroid.recipes.sdl2 import LibSDL2Recipe +from pythonforandroid.util import load_source + +util = load_source('util', os.path.join(os.path.dirname(os.path.dirname(__file__)), 'util.py')) + + +assert LibSDL2Recipe._version == "2.0.9" +assert LibSDL2Recipe.depends == ['sdl2_image', 'sdl2_mixer', 'sdl2_ttf'] +assert LibSDL2Recipe.python_depends == [] + + +class LibSDL2RecipePinned(util.InheritedRecipeMixin, LibSDL2Recipe): + md5sum = None + sha512sum = "a78a4708b2bb5b35a7c7b7501eb3bd60a9aa3bb95a3d84e57763df4a377185e7312a94b66321eef7ca0d17255e4b402fc950e83ef0dbbd08f14ff1194107dc10" + + +recipe = LibSDL2RecipePinned() diff --git a/contrib/android/p4a_recipes/sdl2_image/__init__.py b/contrib/android/p4a_recipes/sdl2_image/__init__.py new file mode 100644 index 000000000..3feed45d1 --- /dev/null +++ b/contrib/android/p4a_recipes/sdl2_image/__init__.py @@ -0,0 +1,18 @@ +import os + +from pythonforandroid.recipes.sdl2_image import LibSDL2Image +from pythonforandroid.util import load_source + +util = load_source('util', os.path.join(os.path.dirname(os.path.dirname(__file__)), 'util.py')) + + +assert LibSDL2Image._version == "2.0.4" +assert LibSDL2Image.depends == [] +assert LibSDL2Image.python_depends == [] + + +class LibSDL2ImageRecipePinned(util.InheritedRecipeMixin, LibSDL2Image): + sha512sum = "7320a5c9111908d402fbb0c12a49eb359a6db645c0c86839793ebb1a5b75eaca7c85eb96851f3a0b4a68a2f06363c8189555afd4f1048a4a41447370eddd7e6a" + + +recipe = LibSDL2ImageRecipePinned() diff --git a/contrib/android/p4a_recipes/sdl2_mixer/__init__.py b/contrib/android/p4a_recipes/sdl2_mixer/__init__.py new file mode 100644 index 000000000..d018783a2 --- /dev/null +++ b/contrib/android/p4a_recipes/sdl2_mixer/__init__.py @@ -0,0 +1,18 @@ +import os + +from pythonforandroid.recipes.sdl2_mixer import LibSDL2Mixer +from pythonforandroid.util import load_source + +util = load_source('util', os.path.join(os.path.dirname(os.path.dirname(__file__)), 'util.py')) + + +assert LibSDL2Mixer._version == "2.0.4" +assert LibSDL2Mixer.depends == [] +assert LibSDL2Mixer.python_depends == [] + + +class LibSDL2MixerPinned(util.InheritedRecipeMixin, LibSDL2Mixer): + sha512sum = "98c56069640668aaececa63748de21fc8f243c7d06386c45c43d0ee472bbb2595ccda644d9886ce5b95c3a3dee3c0a96903cf9a89ddc18d38f041133470699a3" + + +recipe = LibSDL2MixerPinned() diff --git a/contrib/android/p4a_recipes/sdl2_ttf/__init__.py b/contrib/android/p4a_recipes/sdl2_ttf/__init__.py new file mode 100644 index 000000000..6803e8558 --- /dev/null +++ b/contrib/android/p4a_recipes/sdl2_ttf/__init__.py @@ -0,0 +1,18 @@ +import os + +from pythonforandroid.recipes.sdl2_ttf import LibSDL2TTF +from pythonforandroid.util import load_source + +util = load_source('util', os.path.join(os.path.dirname(os.path.dirname(__file__)), 'util.py')) + + +assert LibSDL2TTF._version == "2.0.15" +assert LibSDL2TTF.depends == [] +assert LibSDL2TTF.python_depends == [] + + +class LibSDL2TTFPinned(util.InheritedRecipeMixin, LibSDL2TTF): + sha512sum = "30d685932c3dd6f2c94e2778357a5c502f0421374293d7102a64d92f9c7861229bf36bedf51c1a698b296a58c858ca442d97afb908b7df1592fc8d4f8ae8ddfd" + + +recipe = LibSDL2TTFPinned() diff --git a/contrib/android/p4a_recipes/setuptools/__init__.py b/contrib/android/p4a_recipes/setuptools/__init__.py new file mode 100644 index 000000000..10a26f398 --- /dev/null +++ b/contrib/android/p4a_recipes/setuptools/__init__.py @@ -0,0 +1,13 @@ +from pythonforandroid.recipes.setuptools import SetuptoolsRecipe + + +assert SetuptoolsRecipe._version == "51.3.3" +assert SetuptoolsRecipe.depends == ['python3'] +assert SetuptoolsRecipe.python_depends == [] + + +class SetuptoolsRecipePinned(SetuptoolsRecipe): + sha512sum = "5a3572466a68c6f650111448ce3343f64c62044650bb8635edbff97e2bc7b216b8bbe3b4e3bccf34e6887f3bedc911b27ca5f9a515201cae49cf44fbacf03345" + + +recipe = SetuptoolsRecipePinned() diff --git a/contrib/android/p4a_recipes/six/__init__.py b/contrib/android/p4a_recipes/six/__init__.py new file mode 100644 index 000000000..68eaa2792 --- /dev/null +++ b/contrib/android/p4a_recipes/six/__init__.py @@ -0,0 +1,13 @@ +from pythonforandroid.recipes.six import SixRecipe + + +assert SixRecipe._version == "1.15.0" +assert SixRecipe.depends == ['setuptools', 'python3'] +assert SixRecipe.python_depends == [] + + +class SixRecipePinned(SixRecipe): + sha512sum = "eb840ac17f433f1fc4af56de75cfbfe0b54e6a737bb23c453bf09a4a13d768d153e46064880dc763f4c5cc2785b78ea6d3d3b4a41fed181cb9064837e3f699a9" + + +recipe = SixRecipePinned() diff --git a/contrib/android/p4a_recipes/sqlite3/__init__.py b/contrib/android/p4a_recipes/sqlite3/__init__.py new file mode 100644 index 000000000..70b6bd932 --- /dev/null +++ b/contrib/android/p4a_recipes/sqlite3/__init__.py @@ -0,0 +1,18 @@ +import os + +from pythonforandroid.recipes.sqlite3 import Sqlite3Recipe +from pythonforandroid.util import load_source + +util = load_source('util', os.path.join(os.path.dirname(os.path.dirname(__file__)), 'util.py')) + + +assert Sqlite3Recipe._version == "3.34.1" +assert Sqlite3Recipe.depends == [] +assert Sqlite3Recipe.python_depends == [] + + +class Sqlite3RecipePinned(util.InheritedRecipeMixin, Sqlite3Recipe): + sha512sum = "8a936f1c34fc9036cadf5bd53f9ee594135c2efdef1d2c82bd4fdf3e0218afde710fc4c436cfc992687d008e6086a697da0487352ed88809d677e05d824940dd" + + +recipe = Sqlite3RecipePinned() diff --git a/contrib/android/p4a_recipes/util.py b/contrib/android/p4a_recipes/util.py new file mode 100644 index 000000000..ffdd3ff73 --- /dev/null +++ b/contrib/android/p4a_recipes/util.py @@ -0,0 +1,12 @@ +import os + + +class InheritedRecipeMixin: + + def get_recipe_dir(self): + """This is used to replace pythonforandroid.recipe.Recipe.get_recipe_dir. + If one of our local recipes inherits from a built-in p4a recipe, this override + ensures that potential patches and other local files used by the recipe will + be looked for in the built-in recipe's folder. + """ + return os.path.join(self.ctx.root_dir, 'recipes', self.name)