diff --git a/.github/workflows/push.yml b/.github/workflows/push.yml index b47dac8810..caafb4a073 100644 --- a/.github/workflows/push.yml +++ b/.github/workflows/push.yml @@ -57,7 +57,7 @@ jobs: - name: Build apk for Python 3 ${{ matrix.build-arch }} run: | mkdir -p apks - make docker/run/make/with-artifact/testapps/python3/${{ matrix.build-arch }} + make docker/run/make/with-artifact/testapps/${{ matrix.build-arch }} - uses: actions/upload-artifact@v1 with: name: bdisttest_python3_sqlite_openssl_googlendk__${{ matrix.build-arch }}-debug-1.1.apk diff --git a/.travis.yml b/.travis.yml index c8ad70c91f..7c82accebd 100644 --- a/.travis.yml +++ b/.travis.yml @@ -36,9 +36,6 @@ jobs: - tox -- tests/ --ignore tests/test_pythonpackage.py name: "Tox Pep8" env: TOXENV=pep8 - - <<: *unittests - name: "Tox Python 2" - env: TOXENV=py27 - <<: *unittests name: "Tox Python 3 & Coverage" env: TOXENV=py3 @@ -48,7 +45,7 @@ jobs: name: Python 3 arm64-v8a (with numpy) stage: build testapps before_script: make docker/pull - script: make docker/run/make/testapps/python3/arm64-v8a + script: make docker/run/make/testapps/arm64-v8a - <<: *testapps name: Python 3 armeabi-v7a os: osx @@ -57,10 +54,7 @@ jobs: # installs java 1.8, android's SDK/NDK and p4a - make -f ci/makefiles/osx.mk - export JAVA_HOME=/Library/Java/JavaVirtualMachines/adoptopenjdk-8.jdk/Contents/Home - script: make testapps/python3/armeabi-v7a PYTHON_WITH_VERSION=python3 - - <<: *testapps - name: Python 2 armeabi-v7a - script: make docker/run/make/testapps/python2/armeabi-v7a + script: make testapps/armeabi-v7a PYTHON_WITH_VERSION=python3 - <<: *testapps name: Rebuild updated recipes script: travis_wait 30 make docker/run/make/rebuild_updated_recipes diff --git a/Dockerfile.py2 b/Dockerfile.py2 deleted file mode 100644 index 19418329ca..0000000000 --- a/Dockerfile.py2 +++ /dev/null @@ -1,94 +0,0 @@ -# Dockerfile with: -# - Android build environment -# - python-for-android dependencies -# -# Build with: -# docker build --tag=p4apy2 --file Dockerfile.py2 . -# -# Run with: -# docker run -it --rm p4apy2 /bin/sh -c '. venv/bin/activate && p4a apk --help' -# -# Or for interactive shell: -# docker run -it --rm p4apy2 -# -# Note: -# Use 'docker run' without '--rm' flag for keeping the container and use -# 'docker commit ' to extend the original image - -FROM ubuntu:18.04 - -ENV ANDROID_HOME="/opt/android" - -# configure locale -RUN apt update -qq > /dev/null && apt install -qq --yes --no-install-recommends \ - locales && \ - locale-gen en_US.UTF-8 -ENV LANG="en_US.UTF-8" \ - LANGUAGE="en_US.UTF-8" \ - LC_ALL="en_US.UTF-8" - -RUN apt -y update -qq \ - && apt -y install -qq --no-install-recommends curl unzip ca-certificates \ - && apt -y autoremove - -# retry helper script, refs: -# https://github.com/kivy/python-for-android/issues/1306 -ENV RETRY="retry -t 3 --" -RUN curl https://raw.githubusercontent.com/kadwanev/retry/1.0.1/retry \ - --output /usr/local/bin/retry && chmod +x /usr/local/bin/retry - -ENV USER="user" -ENV HOME_DIR="/home/${USER}" -ENV ANDROID_HOME="${HOME_DIR}/.android" -ENV WORK_DIR="${HOME_DIR}" \ - PATH="${HOME_DIR}/.local/bin:${PATH}" - -# install system dependencies -RUN ${RETRY} apt -y install -qq --no-install-recommends \ - python virtualenv python-pip wget lbzip2 patch sudo \ - && apt -y autoremove \ - && apt -y clean - -# build dependencies -# https://buildozer.readthedocs.io/en/latest/installation.html#android-on-ubuntu-16-04-64bit -RUN dpkg --add-architecture i386 \ - && ${RETRY} apt -y update -qq \ - && ${RETRY} apt -y install -qq --no-install-recommends \ - build-essential ccache git python2.7 python2.7-dev \ - libncurses5:i386 libstdc++6:i386 libgtk2.0-0:i386 \ - libpangox-1.0-0:i386 libpangoxft-1.0-0:i386 libidn11:i386 \ - zip zlib1g-dev zlib1g:i386 \ - && apt -y autoremove - -# specific recipes dependencies (e.g. libffi requires autoreconf binary) -RUN ${RETRY} apt -y install -qq --no-install-recommends \ - libffi-dev autoconf automake cmake gettext libltdl-dev libtool pkg-config \ - && apt -y autoremove \ - && apt -y clean - -# Install Java, set JAVA_HOME (to accept android's SDK licenses) and clean -RUN ${RETRY} apt -y install -qq --no-install-recommends openjdk-8-jdk \ - && apt -y autoremove && apt -y clean -ENV JAVA_HOME /usr/lib/jvm/java-8-openjdk-amd64 - -# prepare non root env -RUN useradd --create-home --shell /bin/bash ${USER} - -# with sudo access and no password -RUN usermod -append --groups sudo ${USER} -RUN echo "%sudo ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers - - -WORKDIR ${WORK_DIR} -COPY --chown=user:user . ${WORK_DIR} -RUN mkdir ${ANDROID_HOME} && chown --recursive ${USER} ${ANDROID_HOME} -USER ${USER} - -# Download and install android's NDK/SDK -RUN make -f ci/makefiles/android.mk target_os=linux - -# install python-for-android from current branch -RUN virtualenv --python=python venv \ - && . venv/bin/activate \ - && pip install --upgrade cython==0.28.6 \ - && pip install -e . diff --git a/Makefile b/Makefile index f1783c9820..1e3566123d 100644 --- a/Makefile +++ b/Makefile @@ -35,18 +35,13 @@ rebuild_updated_recipes: virtualenv ANDROID_SDK_HOME=$(ANDROID_SDK_HOME) ANDROID_NDK_HOME=$(ANDROID_NDK_HOME) \ $(PYTHON) ci/rebuild_updated_recipes.py -testapps/python2/armeabi-v7a: virtualenv - . $(ACTIVATE) && cd testapps/ && \ - python setup_testapp_python2_sqlite_openssl.py apk --sdk-dir $(ANDROID_SDK_HOME) --ndk-dir $(ANDROID_NDK_HOME) \ - --requirements sdl2,pyjnius,kivy,python2,openssl,requests,sqlite3,setuptools - -testapps/python3/arm64-v8a: virtualenv +testapps/arm64-v8a: virtualenv . $(ACTIVATE) && cd testapps/ && \ python setup_testapp_python3_sqlite_openssl.py apk --sdk-dir $(ANDROID_SDK_HOME) --ndk-dir $(ANDROID_NDK_HOME) \ --requirements libffi,sdl2,pyjnius,kivy,python3,openssl,requests,sqlite3,setuptools,numpy \ --arch=arm64-v8a -testapps/python3/armeabi-v7a: virtualenv +testapps/armeabi-v7a: virtualenv . $(ACTIVATE) && cd testapps/ && \ python setup_testapp_python3_sqlite_openssl.py apk --sdk-dir $(ANDROID_SDK_HOME) --ndk-dir $(ANDROID_NDK_HOME) \ --arch=armeabi-v7a @@ -77,11 +72,7 @@ docker/run/make/%: docker/build docker run --rm --env-file=.env $(DOCKER_IMAGE) make $* docker/run/make/with-artifact/%: docker/build -ifeq (,$(findstring python3,$($*))) $(eval $@_APP_NAME := bdisttest_python3_sqlite_openssl_googlendk) -else - $(eval $@_APP_NAME := bdisttest_python2_sqlite_openssl) -endif $(eval $@_APP_ARCH := $(shell basename $*)) docker run --name p4a-latest --env-file=.env $(DOCKER_IMAGE) make $* docker cp p4a-latest:/home/user/app/testapps/$($@_APP_NAME)__$($@_APP_ARCH)-debug-1.1-.apk ./apks diff --git a/README.md b/README.md index bf108c3442..692007bdf3 100644 --- a/README.md +++ b/README.md @@ -102,23 +102,13 @@ new recipe for python3 (3.7.1) had a new build system which was applied to the ancient python recipe, allowing us to bump the python2 version number to 2.7.15. This change unified the build process for both python recipes, and probably solved various issues detected over the -years. It should also be mentioned that these **unified python recipes** -require a **minimum target api level of 21**, -*Android 5.0 - Lollipop*, so in the case that you need to build targeting an +years. These **unified python recipes** require a **minimum target api level of 21**, +*Android 5.0 - Lollipop*. If you need to build targeting an api level below 21, you should use an older version of python-for-android (<=0.7.1). -Be aware that this project is in constant development so, as per time of writing, -you should use a minimum on Android's NDK r19, and ``we recommend using NDK r19b``. -This is because the toolchains installed by -default with the NDK can be used *in-place* and the python-for-android project -has been adapted for that feature. Also be aware that more recent versions of the -Android's NDK may not work. - -Those mentioned changes has been done this way to make easier the transition -between python3 and python2. We will slowly phase out python2 support -towards 2020...so...if you are using python2 in your projects you should -consider migrating it into python3. +On March of 2020 we dropped support for creating apps that use Python 2. The latest +python-for-android release that supported building Python 2 was version 2019.10.6. ## Contributors diff --git a/ci/constants.py b/ci/constants.py index 427d1de4d4..8b79bb5e54 100644 --- a/ci/constants.py +++ b/ci/constants.py @@ -2,59 +2,12 @@ class TargetPython(Enum): - python2 = 0 python3 = 2 # recipes that currently break the build # a recipe could be broken for a target Python and not for the other, # hence we're maintaining one list per Python target -BROKEN_RECIPES_PYTHON2 = set([ - # pythonhelpers.h:12:18: fatal error: string: No such file or directory - 'atom', - # https://github.com/kivy/python-for-android/issues/550 - 'audiostream', - 'brokenrecipe', - 'evdev', - # distutils.errors.DistutilsError - # Could not find suitable distribution for Requirement.parse('cython') - 'ffpyplayer', - 'flask', - 'groestlcoin_hash', - # https://github.com/kivy/python-for-android/issues/1354 - 'kiwisolver', - 'libmysqlclient', - 'libsecp256k1', - 'libtribler', - 'ndghttpsclient', - 'm2crypto', - # ImportError: No module named setuptools - 'netifaces', - 'Pillow', - # depends on cffi that still seems to have compilation issues - 'protobuf_cpp', - 'xeddsa', - 'x3dh', - 'pynacl', - 'doubleratchet', - 'omemo', - # requires `libpq-dev` system dependency e.g. for `pg_config` binary - 'psycopg2', - # most likely some setup in the Docker container, because it works in host - 'pyjnius', 'pyopenal', - 'pyproj', - 'pysdl2', - 'pyzmq', - 'secp256k1', - 'shapely', - # mpmath package with a version >= 0.19 required - 'sympy', - 'twisted', - 'vlc', - 'websocket-client', - 'zeroconf', - 'zope', -]) BROKEN_RECIPES_PYTHON3 = set([ 'brokenrecipe', # enum34 is not compatible with Python 3.6 standard library @@ -76,11 +29,10 @@ class TargetPython(Enum): ]) BROKEN_RECIPES = { - TargetPython.python2: BROKEN_RECIPES_PYTHON2, TargetPython.python3: BROKEN_RECIPES_PYTHON3, } # recipes that were already built will be skipped CORE_RECIPES = set([ 'pyjnius', 'kivy', 'openssl', 'requests', 'sqlite3', 'setuptools', - 'numpy', 'android', 'hostpython2', 'hostpython3', 'python2', 'python3', + 'numpy', 'android', 'hostpython3', 'python3', ]) diff --git a/ci/rebuild_updated_recipes.py b/ci/rebuild_updated_recipes.py index 54f62ac768..d5ecc30cd7 100755 --- a/ci/rebuild_updated_recipes.py +++ b/ci/rebuild_updated_recipes.py @@ -19,15 +19,12 @@ [ERROR]: Didn't find any valid dependency graphs. [ERROR]: This means that some of your requirements pull in conflicting dependencies. - only rebuilds on sdl2 bootstrap -- supports mainly python3 with fallback to python2 """ import sh import os from pythonforandroid.build import Context from pythonforandroid import logger -from pythonforandroid.graph import get_recipe_order_and_bootstrap from pythonforandroid.toolchain import current_directory -from pythonforandroid.util import BuildInterruptingException from pythonforandroid.recipe import Recipe from ci.constants import TargetPython, CORE_RECIPES, BROKEN_RECIPES @@ -55,11 +52,9 @@ def build(target_python, requirements): """ if not requirements: return - testapp = 'setup_testapp_python2.py' + testapp = 'setup_testapp_python3_sqlite_openssl.py' android_sdk_home = os.environ['ANDROID_SDK_HOME'] android_ndk_home = os.environ['ANDROID_NDK_HOME'] - if target_python == TargetPython.python3: - testapp = 'setup_testapp_python3_sqlite_openssl.py' requirements.add(target_python.name) requirements = ','.join(requirements) logger.info('requirements: {}'.format(requirements)) @@ -91,16 +86,6 @@ def main(): 'removed {} from recipes because deleted'.format(recipe_name) ) - # forces the default target - recipes_and_target = recipes | set([target_python.name]) - try: - build_order, python_modules, bs = get_recipe_order_and_bootstrap( - context, recipes_and_target, None) - except BuildInterruptingException: - # fallback to python2 if default target is not compatible - logger.info('incompatible with {}'.format(target_python.name)) - target_python = TargetPython.python2 - logger.info('falling back to {}'.format(target_python.name)) # removing the known broken recipe for the given target broken_recipes = BROKEN_RECIPES[target_python] recipes -= broken_recipes diff --git a/doc/source/buildoptions.rst b/doc/source/buildoptions.rst index 5d80020728..19360ff2fa 100644 --- a/doc/source/buildoptions.rst +++ b/doc/source/buildoptions.rst @@ -8,38 +8,14 @@ This page contains instructions for using different build options. Python versions --------------- -python2 -~~~~~~~ - -Select this by adding it in your requirements, e.g. ``--requirements=python2``. - -This option builds Python 2.7.2 for your selected Android -architecture. There are no special requirements, all the building is -done locally. - - -python3 -~~~~~~~ - -Python3 is supported in two ways. The default method uses CPython 3.7+ -and works with any recent version of the Android NDK. - -Select Python 3 by adding it to your requirements, -e.g. ``--requirements=python3``. - -.. note:: ctypes is not included automatically, if you would like to use it - then add libffi to your requirements, - e.g. ``--requirements=kivy,libffi,python3``. - - -CrystaX python3 -~~~~~~~~~~~~~~~ +python-for-android supports using Python 3.7 or higher. To explicitly select a Python +version in your requirements, use e.g. ``--requirements=python3==3.7.1,hostpython3==3.7.1``. -python-for-android no longer supports building for Python 3 using the CrystaX -NDK. Instead, use the python3 recipe, which can be built using the normal -Google NDK. +The last python-for-android version supporting Python2 was `v2019.10.06 + `__ -.. note:: The last python-for-android version supporting CrystaX was `0.7.0. +Python-for-android no longer supports building for Python 3 using the CrystaX +NDK. The last python-for-android version supporting CrystaX was `0.7.0. `__ .. _bootstrap_build_options: @@ -60,7 +36,7 @@ sdl2 ~~~~ Use this with ``--bootstrap=sdl2``, or just include the -``sdl2`` recipe, e.g. ``--requirements=sdl2,python2``. +``sdl2`` recipe, e.g. ``--requirements=sdl2,python3``. SDL2 is a popular cross-platform depelopment library, particularly for games. It has its own Android project support, which @@ -120,7 +96,7 @@ webview ~~~~~~~ You can use this with ``--bootstrap=webview``, or include the -``webviewjni`` recipe, e.g. ``--requirements=webviewjni,python2``. +``webviewjni`` recipe, e.g. ``--requirements=webviewjni,python3``. The webview bootstrap gui is, per the name, a WebView displaying a webpage, but this page is hosted on the device via a Python diff --git a/doc/source/contribute.rst b/doc/source/contribute.rst index 1de0883c4c..4796c7e411 100644 --- a/doc/source/contribute.rst +++ b/doc/source/contribute.rst @@ -75,9 +75,6 @@ Release checklist - `python3 setup_testapp_python3_sqlite_openssl.py apk` - [ ] `armeabi-v7a` - [ ] `arm64-v8a` - - `python3 setup_testapp_python2.py apk` - - [ ] `armeabi-v7a` - - [ ] `arm64-v8a` - [ ] Check that the version number is correct diff --git a/doc/source/distutils.rst b/doc/source/distutils.rst index 2ee999ffef..74055d0f7a 100644 --- a/doc/source/distutils.rst +++ b/doc/source/distutils.rst @@ -25,9 +25,6 @@ This however has these caveats: or even cause build errors. (Sorry, our internal processing is just not smart enough to honor them properly at this point) -- If you don't use Python 3 per default, you still need to specify - ``--requirements python2`` (without any additional dependencies) - - The dependency analysis at the start may be quite slow and delay your build @@ -117,7 +114,7 @@ store them in setup.py by passing the ``options`` parameter to from setuptools import find_packages options = {'apk': {'debug': None, # use None for arguments that don't pass a value - 'requirements': 'sdl2,pyjnius,kivy,python2', + 'requirements': 'sdl2,pyjnius,kivy,python3', 'android-api': 19, 'ndk-dir': '/path/to/ndk', 'dist-name': 'bdisttest', diff --git a/doc/source/quickstart.rst b/doc/source/quickstart.rst index 07a3fc6523..425a7ea2c2 100644 --- a/doc/source/quickstart.rst +++ b/doc/source/quickstart.rst @@ -185,9 +185,7 @@ an `.apk` file. *Compatibility notes:* -- While python2 is still supported by python-for-android, - it will possibly no longer receive patches by the python creators - themselves in 2020. Migration to Python 3 is recommended! +- Python 2 is no longer supported by python-for-android. The last release supporting Python 2 was v2019.10.06. Build a WebView application diff --git a/doc/source/recipes.rst b/doc/source/recipes.rst index 8702c8d259..c3a97aab4f 100644 --- a/doc/source/recipes.rst +++ b/doc/source/recipes.rst @@ -41,7 +41,7 @@ The basic declaration of a recipe is as follows:: patches = ['some_fix.patch'] # Paths relative to the recipe dir depends = ['kivy', 'sdl2'] # These are just examples - conflicts = ['python2'] + conflicts = ['generickndkbuild'] recipe = YourRecipe() @@ -61,15 +61,15 @@ when the recipe is imported. The actual build process takes place via three core methods:: def prebuild_arch(self, arch): - super(YourRecipe, self).prebuild_arch(arch) + super().prebuild_arch(arch) # Do any pre-initialisation def build_arch(self, arch): - super(YourRecipe, self).build_arch(arch) + super().build_arch(arch) # Do the main recipe build def postbuild_arch(self, arch): - super(YourRecipe, self).build_arch(arch) + super().build_arch(arch) # Do any clearing up These methods are always run in the listed order; prebuild, then @@ -86,7 +86,7 @@ context manager defined in toolchain.py:: from pythonforandroid.toolchain import current_directory def build_arch(self, arch): - super(YourRecipe, self).build_arch(arch) + super().build_arch(arch) with current_directory(self.get_build_dir(arch.arch)): with open('example_file.txt', 'w') as fileh: fileh.write('This is written to a file within the build dir') @@ -178,7 +178,7 @@ environment for any processes that you call. It is convenient to do this using the ``sh`` module as follows:: def build_arch(self, arch): - super(YourRecipe, self).build_arch(arch) + super().build_arch(arch) env = self.get_recipe_env(arch) sh.echo('$PATH', _env=env) # Will print the PATH entry from the # env dict @@ -196,7 +196,7 @@ the following when compiling for SDL2, in order to tell Kivy what backend to use:: def get_recipe_env(self, arch): - env = super(KivySDL2Recipe, self).get_recipe_env(arch) + env = super().get_recipe_env(arch) env['USE_SDL2'] = '1' env['KIVY_SDL2_PATH'] = ':'.join([ @@ -256,7 +256,7 @@ for the Vispy module:: version = 'master' url = 'https://github.com/vispy/vispy/archive/{version}.zip' - depends = ['python2', 'numpy'] + depends = ['python3', 'numpy'] site_packages_name = 'vispy' @@ -272,7 +272,7 @@ Python installation. For reference, the code that accomplishes this is the following:: def build_arch(self, arch): - super(PythonRecipe, self).build_arch(arch) + super().build_arch(arch) self.install_python_package() def install_python_package(self): @@ -426,7 +426,7 @@ overrides if you do not use them:: url = 'http://example.com/example-{version}.tar.gz' # {version} will be replaced with self.version when downloading - depends = ['python2', 'numpy'] # A list of any other recipe names + depends = ['python3', 'numpy'] # A list of any other recipe names # that must be built before this # one @@ -434,7 +434,7 @@ overrides if you do not use them:: # alongside this one def get_recipe_env(self, arch): - env = super(YourRecipe, self).get_recipe_env(arch) + env = super().get_recipe_env(arch) # Manipulate the env here if you want return env @@ -444,19 +444,19 @@ overrides if you do not use them:: return True def prebuild_arch(self, arch): - super(YourRecipe, self).prebuild_arch(self) + super().prebuild_arch(self) # Do any extra prebuilding you want, e.g.: self.apply_patch('path/to/patch.patch') def build_arch(self, arch): - super(YourRecipe, self).build_arch(self) + super().build_arch(self) # Build the code. Make sure to use the right build dir, e.g. with current_directory(self.get_build_dir(arch.arch)): sh.ls('-lathr') # Or run some commands that actually do # something def postbuild_arch(self, arch): - super(YourRecipe, self).prebuild_arch(self) + super().prebuild_arch(self) # Do anything you want after the build, e.g. deleting # unnecessary files such as documentation diff --git a/doc/source/troubleshooting.rst b/doc/source/troubleshooting.rst index 4277d51bbf..5974718308 100644 --- a/doc/source/troubleshooting.rst +++ b/doc/source/troubleshooting.rst @@ -132,8 +132,8 @@ AttributeError: 'Context' object has no attribute 'hostpython' This is a known bug in some releases. To work around it, add your python requirement explicitly, -e.g. :code:`--requirements=python2,kivy`. This also applies when using -buildozer, in which case add python2 to your buildozer.spec requirements. +e.g. :code:`--requirements=python3,kivy`. This also applies when using +buildozer, in which case add python3 to your buildozer.spec requirements. linkname too long ~~~~~~~~~~~~~~~~~ diff --git a/pythonforandroid/bootstrap.py b/pythonforandroid/bootstrap.py index 03925a3e01..e85dc74732 100755 --- a/pythonforandroid/bootstrap.py +++ b/pythonforandroid/bootstrap.py @@ -78,7 +78,7 @@ class Bootstrap(object): distribution = None # All bootstraps should include Python in some way: - recipe_depends = [("python2", "python3"), 'android'] + recipe_depends = ['python3', 'android'] can_be_chosen_automatically = True '''Determines whether the bootstrap can be chosen as one that diff --git a/pythonforandroid/bootstraps/common/build/build.py b/pythonforandroid/bootstraps/common/build/build.py index 07a5be01d8..fea791db8d 100644 --- a/pythonforandroid/bootstraps/common/build/build.py +++ b/pythonforandroid/bootstraps/common/build/build.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python2.7 +#!/usr/bin/env python3 from __future__ import print_function @@ -16,7 +16,6 @@ import tarfile import tempfile import time -from zipfile import ZipFile from distutils.version import LooseVersion from fnmatch import fnmatch @@ -78,10 +77,6 @@ def get_bootstrap_name(): # pyc/py if PYTHON is not None: BLACKLIST_PATTERNS.append('*.py') - if PYTHON_VERSION and int(PYTHON_VERSION[0]) == 2: - # we only blacklist `.pyc` for python2 because in python3 the compiled - # extension is `.pyc` (.pyo files not exists for python >= 3.6) - BLACKLIST_PATTERNS.append('*.pyc') WHITELIST_PATTERNS = [] if get_bootstrap_name() in ('sdl2', 'webview', 'service_only'): @@ -156,48 +151,6 @@ def listfiles(d): yield fn -def make_python_zip(): - ''' - Search for all the python related files, and construct the pythonXX.zip - According to - # http://randomsplat.com/id5-cross-compiling-python-for-embedded-linux.html - site-packages, config and lib-dynload will be not included. - ''' - - if not exists('private'): - print('No compiled python is present to zip, skipping.') - return - - global python_files - d = realpath(join('private', 'lib', 'python2.7')) - - def select(fn): - if is_blacklist(fn): - return False - fn = realpath(fn) - assert(fn.startswith(d)) - fn = fn[len(d):] - if (fn.startswith('/site-packages/') - or fn.startswith('/config/') - or fn.startswith('/lib-dynload/') - or fn.startswith('/libpymodules.so')): - return False - return fn - - # get a list of all python file - python_files = [x for x in listfiles(d) if select(x)] - - # create the final zipfile - zfn = join('private', 'lib', 'python27.zip') - zf = ZipFile(zfn, 'w') - - # put all the python files in it - for fn in python_files: - afn = fn[len(d):] - zf.write(fn, afn) - zf.close() - - def make_tar(tfn, source_dirs, ignore_path=[], optimize_python=True): ''' Make a zip file `fn` from the contents of source_dis. @@ -292,10 +245,6 @@ def make_package(args): try_unlink(join(assets_dir, 'private.mp3')) ensure_dir(assets_dir) - # In order to speedup import and initial depack, - # construct a python27.zip - make_python_zip() - # Add extra environment variable file into tar-able directory: env_vars_tarpath = tempfile.mkdtemp(prefix="p4a-extra-env-") with open(os.path.join(env_vars_tarpath, "p4a_env_vars.txt"), "w") as f: diff --git a/pythonforandroid/bootstraps/common/build/jni/application/src/start.c b/pythonforandroid/bootstraps/common/build/jni/application/src/start.c index 24297accdb..f57098069f 100644 --- a/pythonforandroid/bootstraps/common/build/jni/application/src/start.c +++ b/pythonforandroid/bootstraps/common/build/jni/application/src/start.c @@ -189,17 +189,6 @@ int main(int argc, char *argv[]) { } Py_Initialize(); - -#if PY_MAJOR_VERSION < 3 - // Can't Py_SetPath in python2 but we can set PySys_SetPath, which must - // be applied after Py_Initialize rather than before like Py_SetPath - #if PY_MICRO_VERSION >= 15 - // Only for python native-build - PySys_SetPath(paths); - #endif - PySys_SetArgv(argc, argv); -#endif - LOGP("Initialized python"); /* ensure threads will work. @@ -285,7 +274,7 @@ int main(int argc, char *argv[]) { entrypoint[strlen(env_entrypoint) - 1] = '\0'; LOGP(entrypoint); if (!file_exists(entrypoint)) { - LOGP("Entrypoint not found (.pyc/.pyo, fallback on .py), abort"); + LOGP("Entrypoint not found (.pyc, fallback on .py), abort"); return -1; } } else { @@ -309,7 +298,7 @@ int main(int argc, char *argv[]) { strcpy(entrypoint, env_entrypoint); } } else { - LOGP("Entrypoint have an invalid extension (must be .py or .pyc/.pyo), abort."); + LOGP("Entrypoint have an invalid extension (must be .py or .pyc), abort."); return -1; } // LOGP("Entrypoint is:"); @@ -330,8 +319,7 @@ int main(int argc, char *argv[]) { ret = 1; PyErr_Print(); /* This exits with the right code if SystemExit. */ PyObject *f = PySys_GetObject("stdout"); - if (PyFile_WriteString( - "\n", f)) /* python2 used Py_FlushLine, but this no longer exists */ + if (PyFile_WriteString("\n", f)) PyErr_Clear(); } diff --git a/pythonforandroid/bootstraps/common/build/src/main/java/org/kivy/android/PythonUtil.java b/pythonforandroid/bootstraps/common/build/src/main/java/org/kivy/android/PythonUtil.java index 2bb1cf3607..6a546a7eb1 100644 --- a/pythonforandroid/bootstraps/common/build/src/main/java/org/kivy/android/PythonUtil.java +++ b/pythonforandroid/bootstraps/common/build/src/main/java/org/kivy/android/PythonUtil.java @@ -36,7 +36,6 @@ protected static ArrayList getLibraries(File libsDir) { addLibraryIfExists(libsList, "ffi", libsDir); addLibraryIfExists(libsList, "ssl.*", libsDir); addLibraryIfExists(libsList, "crypto.*", libsDir); - libsList.add("python2.7"); libsList.add("python3.5m"); libsList.add("python3.6m"); libsList.add("python3.7m"); diff --git a/pythonforandroid/bootstraps/sdl2/build/src/main/java/org/kivy/android/PythonUtil.java b/pythonforandroid/bootstraps/sdl2/build/src/main/java/org/kivy/android/PythonUtil.java index 460f704190..84540f55a8 100644 --- a/pythonforandroid/bootstraps/sdl2/build/src/main/java/org/kivy/android/PythonUtil.java +++ b/pythonforandroid/bootstraps/sdl2/build/src/main/java/org/kivy/android/PythonUtil.java @@ -40,7 +40,6 @@ protected static ArrayList getLibraries(File libsDir) { libsList.add("SDL2_ttf"); addLibraryIfExists(libsList, "ssl.*", libsDir); addLibraryIfExists(libsList, "crypto.*", libsDir); - libsList.add("python2.7"); libsList.add("python3.5m"); libsList.add("python3.6m"); libsList.add("python3.7m"); @@ -76,20 +75,6 @@ public static void loadLibraries(File filesDir, File libsDir) { } } - try { - System.load(filesDirPath + "/lib/python2.7/lib-dynload/_io.so"); - System.load(filesDirPath + "/lib/python2.7/lib-dynload/unicodedata.so"); - } catch(UnsatisfiedLinkError e) { - Log.v(TAG, "Failed to load _io.so or unicodedata.so...but that's okay."); - } - - try { - // System.loadLibrary("ctypes"); - System.load(filesDirPath + "/lib/python2.7/lib-dynload/_ctypes.so"); - } catch(UnsatisfiedLinkError e) { - Log.v(TAG, "Unsatisfied linker when loading ctypes"); - } - Log.v(TAG, "Loaded everything!"); } } diff --git a/pythonforandroid/python.py b/pythonforandroid/python.py index 9c8b2439a2..9d180ca7e7 100755 --- a/pythonforandroid/python.py +++ b/pythonforandroid/python.py @@ -1,6 +1,6 @@ ''' This module is kind of special because it contains the base classes used to -build our python3 and python2 recipes and his corresponding hostpython recipes. +build our python3 and his corresponding hostpython recipes. ''' from os.path import dirname, exists, join, isfile @@ -26,8 +26,7 @@ class GuestPythonRecipe(TargetPythonRecipe): Class for target python recipes. Sets ctx.python_recipe to point to itself, so as to know later what kind of Python was built or used. - This base class is used for our main python recipes (python2 and python3) - which shares most of the build process. + This base class is used for our main python3 recipe. .. versionadded:: 0.6.0 Refactored from the inclement's python3 recipe with a few changes: @@ -280,10 +279,7 @@ def compile_python_files(self, dir): longer used...uses .pyc (https://www.python.org/dev/peps/pep-0488) ''' args = [self.ctx.hostpython] - if self.ctx.python_recipe.name == 'python3': - args += ['-OO', '-m', 'compileall', '-b', '-f', dir] - else: - args += ['-OO', '-m', 'compileall', '-f', dir] + args += ['-OO', '-m', 'compileall', '-b', '-f', dir] subprocess.call(args) def create_python_bundle(self, dirn, arch): @@ -363,7 +359,7 @@ def create_python_bundle(self, dirn, arch): class HostPythonRecipe(Recipe): ''' - This is the base class for hostpython3 and hostpython2 recipes. This class + This is the base class for hostpython3 recipe. This class will take care to do all the work to build a hostpython recipe but, be careful, it is intended to be subclassed because some of the vars needs to be set: @@ -376,8 +372,7 @@ class HostPythonRecipe(Recipe): ''' name = '' - '''The hostpython's recipe name. This should be ``hostpython2`` or - ``hostpython3`` + '''The hostpython's recipe name. This should be ``hostpython3`` .. warning:: This must be set in inherited class.''' diff --git a/pythonforandroid/recipe.py b/pythonforandroid/recipe.py index 3d814d5c4e..c9d721a7d4 100644 --- a/pythonforandroid/recipe.py +++ b/pythonforandroid/recipe.py @@ -843,7 +843,7 @@ class PythonRecipe(Recipe): setup_extra_args = [] '''List of extra arguments to pass to setup.py''' - depends = [('python2', 'python3')] + depends = ['python3'] ''' .. note:: it's important to keep this depends as a class attribute outside `__init__` because sometimes we only initialize the class, so the @@ -857,19 +857,13 @@ class PythonRecipe(Recipe): def __init__(self, *args, **kwargs): super(PythonRecipe, self).__init__(*args, **kwargs) - if not any( - [ - d - for d in {'python2', 'python3', ('python2', 'python3')} - if d in self.depends - ] - ): + if 'python3' not in self.depends: # We ensure here that the recipe depends on python even it overrode # `depends`. We only do this if it doesn't already depend on any # python, since some recipes intentionally don't depend on/work # with all python variants depends = self.depends - depends.append(('python2', 'python3')) + depends.append('python3') depends = list(set(depends)) self.depends = depends @@ -889,7 +883,7 @@ def clean_build(self, arch=None): @property def real_hostpython_location(self): host_name = 'host{}'.format(self.ctx.python_recipe.name) - if host_name in ['hostpython2', 'hostpython3']: + if host_name == 'hostpython3': python_recipe = Recipe.get_recipe(host_name, self.ctx) return python_recipe.python_exe else: diff --git a/pythonforandroid/recipes/android/__init__.py b/pythonforandroid/recipes/android/__init__.py index 3658c772ba..b2563f7301 100644 --- a/pythonforandroid/recipes/android/__init__.py +++ b/pythonforandroid/recipes/android/__init__.py @@ -1,7 +1,6 @@ from __future__ import unicode_literals from pythonforandroid.recipe import CythonRecipe, IncludedFilesBehaviour from pythonforandroid.util import current_directory -from pythonforandroid.patching import will_build from pythonforandroid import logger from os.path import join @@ -56,7 +55,7 @@ def prebuild_arch(self, arch): config = { 'BOOTSTRAP': bootstrap, 'IS_SDL2': int(is_sdl2), - 'PY2': int(will_build('python2')(self)), + 'PY2': 0, 'JAVA_NAMESPACE': java_ns, 'JNI_NAMESPACE': jni_ns, } diff --git a/pythonforandroid/recipes/apsw/__init__.py b/pythonforandroid/recipes/apsw/__init__.py index 6098e4b98c..542bdef81b 100644 --- a/pythonforandroid/recipes/apsw/__init__.py +++ b/pythonforandroid/recipes/apsw/__init__.py @@ -6,7 +6,7 @@ class ApswRecipe(PythonRecipe): version = '3.15.0-r1' url = 'https://github.com/rogerbinns/apsw/archive/{version}.tar.gz' - depends = ['sqlite3', ('python2', 'python3'), 'setuptools'] + depends = ['sqlite3', 'setuptools'] call_hostpython_via_targetpython = False site_packages_name = 'apsw' diff --git a/pythonforandroid/recipes/audiostream/__init__.py b/pythonforandroid/recipes/audiostream/__init__.py index 518d1dda8e..1e9d388ebc 100644 --- a/pythonforandroid/recipes/audiostream/__init__.py +++ b/pythonforandroid/recipes/audiostream/__init__.py @@ -7,7 +7,7 @@ class AudiostreamRecipe(CythonRecipe): version = 'master' url = 'https://github.com/kivy/audiostream/archive/{version}.zip' name = 'audiostream' - depends = [('python2', 'python3'), 'sdl2', 'pyjnius'] + depends = ['python3', 'sdl2', 'pyjnius'] def get_recipe_env(self, arch): env = super(AudiostreamRecipe, self).get_recipe_env(arch) diff --git a/pythonforandroid/recipes/boost/__init__.py b/pythonforandroid/recipes/boost/__init__.py index 978ab6f5b0..921ed21eb0 100644 --- a/pythonforandroid/recipes/boost/__init__.py +++ b/pythonforandroid/recipes/boost/__init__.py @@ -39,7 +39,7 @@ class BoostRecipe(Recipe): 'http://downloads.sourceforge.net/project/boost/' 'boost/{version}/boost_{version_underscore}.tar.bz2' ) - depends = [('python2', 'python3')] + depends = ['python3'] patches = [ 'disable-so-version.patch', 'use-android-libs.patch', diff --git a/pythonforandroid/recipes/coverage/__init__.py b/pythonforandroid/recipes/coverage/__init__.py index 95f08f1f4a..2ee2d059c8 100644 --- a/pythonforandroid/recipes/coverage/__init__.py +++ b/pythonforandroid/recipes/coverage/__init__.py @@ -7,7 +7,7 @@ class CoverageRecipe(PythonRecipe): url = 'https://pypi.python.org/packages/2d/10/6136c8e10644c16906edf4d9f7c782c0f2e7ed47ff2f41f067384e432088/coverage-{version}.tar.gz' - depends = [('hostpython2', 'hostpython3'), 'setuptools'] + depends = ['hostpython3', 'setuptools'] patches = ['fallback-utf8.patch'] diff --git a/pythonforandroid/recipes/ffpyplayer/__init__.py b/pythonforandroid/recipes/ffpyplayer/__init__.py index cb9e7071e7..d8fd6ce77d 100644 --- a/pythonforandroid/recipes/ffpyplayer/__init__.py +++ b/pythonforandroid/recipes/ffpyplayer/__init__.py @@ -6,7 +6,7 @@ class FFPyPlayerRecipe(CythonRecipe): version = 'c99913f2317bf3840eeacf1c1c3db3b3d1f78007' url = 'https://github.com/matham/ffpyplayer/archive/{version}.zip' - depends = [('python2', 'python3'), 'sdl2', 'ffmpeg'] + depends = ['python3', 'sdl2', 'ffmpeg'] opt_depends = ['openssl', 'ffpyplayer_codecs'] def get_recipe_env(self, arch, with_flags_in_cc=True): diff --git a/pythonforandroid/recipes/genericndkbuild/__init__.py b/pythonforandroid/recipes/genericndkbuild/__init__.py index e6cccb6e8d..be08098db1 100644 --- a/pythonforandroid/recipes/genericndkbuild/__init__.py +++ b/pythonforandroid/recipes/genericndkbuild/__init__.py @@ -7,7 +7,7 @@ class GenericNDKBuildRecipe(BootstrapNDKRecipe): version = None url = None - depends = [('python2', 'python3')] + depends = ['python3'] conflicts = ['sdl2'] def should_build(self, arch): diff --git a/pythonforandroid/recipes/hostpython2/__init__.py b/pythonforandroid/recipes/hostpython2/__init__.py deleted file mode 100644 index 36eb178d8a..0000000000 --- a/pythonforandroid/recipes/hostpython2/__init__.py +++ /dev/null @@ -1,18 +0,0 @@ -from pythonforandroid.python import HostPythonRecipe - - -class Hostpython2Recipe(HostPythonRecipe): - ''' - The hostpython2's recipe. - - .. versionchanged:: 0.6.0 - Updated to version 2.7.15 and the build process has been changed in - favour of the recently added class - :class:`~pythonforandroid.python.HostPythonRecipe` - ''' - version = '2.7.15' - name = 'hostpython2' - conflicts = ['hostpython3'] - - -recipe = Hostpython2Recipe() diff --git a/pythonforandroid/recipes/hostpython3/__init__.py b/pythonforandroid/recipes/hostpython3/__init__.py index 3068b85da4..82619c64c7 100644 --- a/pythonforandroid/recipes/hostpython3/__init__.py +++ b/pythonforandroid/recipes/hostpython3/__init__.py @@ -11,7 +11,6 @@ class Hostpython3Recipe(HostPythonRecipe): ''' version = '3.8.1' name = 'hostpython3' - conflicts = ['hostpython2'] recipe = Hostpython3Recipe() diff --git a/pythonforandroid/recipes/icu/__init__.py b/pythonforandroid/recipes/icu/__init__.py index 43c5ac9eb8..b147455b05 100644 --- a/pythonforandroid/recipes/icu/__init__.py +++ b/pythonforandroid/recipes/icu/__init__.py @@ -14,7 +14,7 @@ class ICURecipe(Recipe): url = ('http://download.icu-project.org/files/icu4c/' '{version}/icu4c-{version_underscore}-src.tgz') - depends = [('hostpython2', 'hostpython3')] # installs in python + depends = ['hostpython3'] # installs in python patches = ['disable-libs-version.patch'] built_libraries = { diff --git a/pythonforandroid/recipes/ifaddrs/__init__.py b/pythonforandroid/recipes/ifaddrs/__init__.py index 47c0008fa5..7d44f9cd72 100644 --- a/pythonforandroid/recipes/ifaddrs/__init__.py +++ b/pythonforandroid/recipes/ifaddrs/__init__.py @@ -10,7 +10,7 @@ class IFAddrRecipe(CompiledComponentsPythonRecipe): version = '8f9a87c' url = 'https://github.com/morristech/android-ifaddrs/archive/{version}.zip' - depends = [('hostpython2', 'hostpython3')] + depends = ['hostpython3'] call_hostpython_via_targetpython = False site_packages_name = 'ifaddrs' diff --git a/pythonforandroid/recipes/libglob/__init__.py b/pythonforandroid/recipes/libglob/__init__.py index 4c69657c87..f63db42628 100644 --- a/pythonforandroid/recipes/libglob/__init__.py +++ b/pythonforandroid/recipes/libglob/__init__.py @@ -22,7 +22,7 @@ class LibGlobRecipe(Recipe): name = 'libglob' built_libraries = {'libglob.so': '.'} - depends = [('hostpython2', 'hostpython3')] + depends = ['hostpython3'] patches = ['glob.patch'] def should_build(self, arch): diff --git a/pythonforandroid/recipes/libnacl/__init__.py b/pythonforandroid/recipes/libnacl/__init__.py index 3fc5da82f0..50689feb5d 100644 --- a/pythonforandroid/recipes/libnacl/__init__.py +++ b/pythonforandroid/recipes/libnacl/__init__.py @@ -4,7 +4,7 @@ class LibNaClRecipe(PythonRecipe): version = '1.4.4' url = 'https://github.com/saltstack/libnacl/archive/v{version}.tar.gz' - depends = [('hostpython2', 'hostpython3'), 'setuptools', 'libsodium'] + depends = ['hostpython3', 'setuptools', 'libsodium'] site_packages_name = 'libnacl' call_hostpython_via_targetpython = False diff --git a/pythonforandroid/recipes/matplotlib/__init__.py b/pythonforandroid/recipes/matplotlib/__init__.py index 05fa5c424b..277dada75f 100644 --- a/pythonforandroid/recipes/matplotlib/__init__.py +++ b/pythonforandroid/recipes/matplotlib/__init__.py @@ -12,7 +12,6 @@ class MatplotlibRecipe(CppCompiledComponentsPythonRecipe): url = 'https://github.com/matplotlib/matplotlib/archive/v{version}.zip' depends = ['numpy', 'png', 'setuptools', 'freetype', 'kiwisolver'] - conflicts = ['python2'] python_depends = ['pyparsing', 'cycler', 'python-dateutil'] diff --git a/pythonforandroid/recipes/mysqldb/__init__.py b/pythonforandroid/recipes/mysqldb/__init__.py index f08458567b..0559782cff 100644 --- a/pythonforandroid/recipes/mysqldb/__init__.py +++ b/pythonforandroid/recipes/mysqldb/__init__.py @@ -31,7 +31,7 @@ def prebuild_arch(self, arch): def get_recipe_env(self, arch=None): env = super(MysqldbRecipe, self).get_recipe_env(arch) - hostpython = self.get_recipe('hostpython2', self.ctx) + hostpython = self.get_recipe('hostpython3', self.ctx) # TODO: fix hardcoded path env['PYTHONPATH'] = (join(hostpython.get_build_dir(arch.arch), 'build', 'lib.linux-x86_64-2.7') + diff --git a/pythonforandroid/recipes/ndghttpsclient b/pythonforandroid/recipes/ndghttpsclient index 35e996f0d6..bfe581a119 100644 --- a/pythonforandroid/recipes/ndghttpsclient +++ b/pythonforandroid/recipes/ndghttpsclient @@ -1,9 +1,9 @@ from pythonforandroid.recipe import PythonRecipe class NdgHttpsClientRecipe(PythonRecipe): - version = '0.4.0' + version = '0.5.1' url = 'https://pypi.python.org/packages/source/n/ndg-httpsclient/ndg_httpsclient-{version}.tar.gz' - depends = ['python2', 'pyopenssl', 'cryptography'] + depends = ['python3', 'pyopenssl', 'cryptography'] call_hostpython_via_targetpython = False recipe = NdgHttpsClientRecipe() diff --git a/pythonforandroid/recipes/numpy/__init__.py b/pythonforandroid/recipes/numpy/__init__.py index 1d78e6c083..334886f792 100644 --- a/pythonforandroid/recipes/numpy/__init__.py +++ b/pythonforandroid/recipes/numpy/__init__.py @@ -18,11 +18,6 @@ class NumpyRecipe(CompiledComponentsPythonRecipe): call_hostpython_via_targetpython = False - def apply_patches(self, arch, build_dir=None): - if 'python2' in self.ctx.recipe_build_order: - self.patches.append(join('patches', 'fix-py2-numpy-import.patch')) - super().apply_patches(arch, build_dir=build_dir) - def build_compiled_components(self, arch): self.setup_extra_args = ['-j', str(cpu_count())] super().build_compiled_components(arch) diff --git a/pythonforandroid/recipes/numpy/patches/fix-py2-numpy-import.patch b/pythonforandroid/recipes/numpy/patches/fix-py2-numpy-import.patch deleted file mode 100644 index e75bd37dfd..0000000000 --- a/pythonforandroid/recipes/numpy/patches/fix-py2-numpy-import.patch +++ /dev/null @@ -1,15 +0,0 @@ -There is an open issue at numpy talking about the import error with numpy: - https://github.com/numpy/numpy/issues/13248 -The solution applied here is mentioned there and it seems to only affect our -python2 version. ---- numpy-1.16.4/numpy/core/overrides.py.orig 2019-05-27 12:41:06.000000000 +0200 -+++ numpy-1.16.4/numpy/core/overrides.py 2019-10-13 18:51:06.387037239 +0200 -@@ -140,6 +140,8 @@ def array_function_dispatch(dispatcher, - ------- - Function suitable for decorating the implementation of a NumPy function. - """ -+ if dispatcher.__doc__ is None: -+ dispatcher.__doc__ = "" - - if not ENABLE_ARRAY_FUNCTION: - # __array_function__ requires an explicit opt-in for now diff --git a/pythonforandroid/recipes/pandas/__init__.py b/pythonforandroid/recipes/pandas/__init__.py index 7999d02402..1432f81f5f 100644 --- a/pythonforandroid/recipes/pandas/__init__.py +++ b/pythonforandroid/recipes/pandas/__init__.py @@ -8,7 +8,6 @@ class PandasRecipe(CppCompiledComponentsPythonRecipe): url = 'https://github.com/pandas-dev/pandas/releases/download/v{version}/pandas-{version}.tar.gz' # noqa depends = ['cython', 'numpy', 'pytz', 'libbz2', 'liblzma'] - conflicts = ['python2'] python_depends = ['python-dateutil'] patches = ['fix_numpy_includes.patch'] diff --git a/pythonforandroid/recipes/pycrypto/__init__.py b/pythonforandroid/recipes/pycrypto/__init__.py index 8f70df28e9..479eca44c9 100644 --- a/pythonforandroid/recipes/pycrypto/__init__.py +++ b/pythonforandroid/recipes/pycrypto/__init__.py @@ -10,7 +10,7 @@ class PyCryptoRecipe(CompiledComponentsPythonRecipe): version = '2.7a1' url = 'https://github.com/dlitz/pycrypto/archive/v{version}.zip' - depends = ['openssl', ('python2', 'python3')] + depends = ['openssl', 'python3'] site_packages_name = 'Crypto' call_hostpython_via_targetpython = False patches = ['add_length.patch'] diff --git a/pythonforandroid/recipes/pynacl/__init__.py b/pythonforandroid/recipes/pynacl/__init__.py index eb9ca2df50..4170368f9b 100644 --- a/pythonforandroid/recipes/pynacl/__init__.py +++ b/pythonforandroid/recipes/pynacl/__init__.py @@ -7,7 +7,7 @@ class PyNaCLRecipe(CompiledComponentsPythonRecipe): version = '1.3.0' url = 'https://pypi.python.org/packages/source/P/PyNaCl/PyNaCl-{version}.tar.gz' - depends = [('hostpython2', 'hostpython3'), 'six', 'setuptools', 'cffi', 'libsodium'] + depends = ['hostpython3', 'six', 'setuptools', 'cffi', 'libsodium'] call_hostpython_via_targetpython = False def get_recipe_env(self, arch): diff --git a/pythonforandroid/recipes/python2/__init__.py b/pythonforandroid/recipes/python2/__init__.py deleted file mode 100644 index 0f14e5e617..0000000000 --- a/pythonforandroid/recipes/python2/__init__.py +++ /dev/null @@ -1,83 +0,0 @@ -from os.path import join, exists -from pythonforandroid.recipe import Recipe -from pythonforandroid.python import GuestPythonRecipe -from pythonforandroid.logger import shprint, warning -import sh - - -class Python2Recipe(GuestPythonRecipe): - ''' - The python2's recipe. - - .. note:: This recipe can be built only against API 21+ - - .. versionchanged:: 0.6.0 - Updated to version 2.7.15 and the build process has been changed in - favour of the recently added class - :class:`~pythonforandroid.python.GuestPythonRecipe` - ''' - version = "2.7.15" - url = 'https://www.python.org/ftp/python/{version}/Python-{version}.tgz' - name = 'python2' - - depends = ['hostpython2', 'libffi'] - conflicts = ['python3'] - - patches = [ - # new 2.7.15 patches - # ('patches/fix-api-minor-than-21.patch', - # is_api_lt(21)), # Todo: this should be tested - 'patches/fix-missing-extensions.patch', - 'patches/fix-filesystem-default-encoding.patch', - 'patches/fix-gethostbyaddr.patch', - 'patches/fix-posix-declarations.patch', - 'patches/fix-pwd-gecos.patch', - 'patches/fix-ctypes-util-find-library.patch', - 'patches/fix-interpreter-version.patch', - 'patches/fix-zlib-version.patch', - ] - - configure_args = ('--host={android_host}', - '--build={android_build}', - '--enable-shared', - '--disable-ipv6', - '--disable-toolbox-glue', - '--disable-framework', - 'ac_cv_file__dev_ptmx=yes', - 'ac_cv_file__dev_ptc=no', - '--without-ensurepip', - 'ac_cv_little_endian_double=yes', - 'ac_cv_header_langinfo_h=no', - '--prefix={prefix}', - '--exec-prefix={exec_prefix}') - - compiled_extension = '.pyo' - - def prebuild_arch(self, arch): - super(Python2Recipe, self).prebuild_arch(arch) - patch_mark = join(self.get_build_dir(arch.arch), '.openssl-patched') - if 'openssl' in self.ctx.recipe_build_order and not exists(patch_mark): - self.apply_patch(join('patches', 'enable-openssl.patch'), arch.arch) - shprint(sh.touch, patch_mark) - - def build_arch(self, arch): - warning('DEPRECATION: Support for the Python 2 recipe will be ' - 'removed in 2020, please upgrade to Python 3.') - super().build_arch(arch) - - def set_libs_flags(self, env, arch): - env = super(Python2Recipe, self).set_libs_flags(env, arch) - if 'libffi' in self.ctx.recipe_build_order: - # For python2 we need to tell configure that we want to use our - # compiled libffi, this step is not necessary for python3. - self.configure_args += ('--with-system-ffi',) - - if 'openssl' in self.ctx.recipe_build_order: - recipe = Recipe.get_recipe('openssl', self.ctx) - openssl_build = recipe.get_build_dir(arch.arch) - env['OPENSSL_BUILD'] = openssl_build - env['OPENSSL_VERSION'] = recipe.version - return env - - -recipe = Python2Recipe() diff --git a/pythonforandroid/recipes/python2/patches/enable-openssl.patch b/pythonforandroid/recipes/python2/patches/enable-openssl.patch deleted file mode 100644 index 490e065c5f..0000000000 --- a/pythonforandroid/recipes/python2/patches/enable-openssl.patch +++ /dev/null @@ -1,46 +0,0 @@ ---- Python-2.7.15.orig/setup.py 2018-04-30 00:47:33.000000000 +0200 -+++ Python-2.7.15/setup.py 2018-07-05 11:08:57.305125432 +0200 -@@ -812,18 +840,15 @@ class PyBuildExt(build_ext): - '/usr/local/ssl/include', - '/usr/contrib/ssl/include/' - ] -- ssl_incs = find_file('openssl/ssl.h', inc_dirs, -- search_for_ssl_incs_in -- ) -+ ssl_incs = [ -+ os.path.join(os.environ["OPENSSL_BUILD"], 'include'), -+ os.path.join(os.environ["OPENSSL_BUILD"], 'include', 'openssl')] - if ssl_incs is not None: - krb5_h = find_file('krb5.h', inc_dirs, - ['/usr/kerberos/include']) - if krb5_h: - ssl_incs += krb5_h -- ssl_libs = find_library_file(self.compiler, 'ssl',lib_dirs, -- ['/usr/local/ssl/lib', -- '/usr/contrib/ssl/lib/' -- ] ) -+ ssl_libs = [os.environ["OPENSSL_BUILD"]] - - if (ssl_incs is not None and - ssl_libs is not None): -@@ -841,8 +866,8 @@ class PyBuildExt(build_ext): - '^\s*#\s*define\s+OPENSSL_VERSION_NUMBER\s+(0x[0-9a-fA-F]+)' ) - - # look for the openssl version header on the compiler search path. -- opensslv_h = find_file('openssl/opensslv.h', [], -- inc_dirs + search_for_ssl_incs_in) -+ opensslv_h = [os.path.join(os.environ["OPENSSL_BUILD"], 'include'), -+ os.path.join(os.environ["OPENSSL_BUILD"], 'include', 'openssl')] - if opensslv_h: - name = os.path.join(opensslv_h[0], 'openssl/opensslv.h') - if host_platform == 'darwin' and is_macosx_sdk_path(name): -@@ -859,8 +884,7 @@ class PyBuildExt(build_ext): - - min_openssl_ver = 0x00907000 - have_any_openssl = ssl_incs is not None and ssl_libs is not None -- have_usable_openssl = (have_any_openssl and -- openssl_ver >= min_openssl_ver) -+ have_usable_openssl = (have_any_openssl and True) - - if have_any_openssl: - if have_usable_openssl: diff --git a/pythonforandroid/recipes/python2/patches/fix-api-minor-than-21.patch b/pythonforandroid/recipes/python2/patches/fix-api-minor-than-21.patch deleted file mode 100644 index 73dfc981ec..0000000000 --- a/pythonforandroid/recipes/python2/patches/fix-api-minor-than-21.patch +++ /dev/null @@ -1,229 +0,0 @@ -diff -Naurp Python-2.7.15.orig/configure.ac Python-2.7.15/configure.ac ---- Python-2.7.15.orig/configure.ac 2018-04-30 00:47:33.000000000 +0200 -+++ Python-2.7.15/configure.ac 2018-07-05 17:44:50.500985727 +0200 -@@ -1790,7 +1790,7 @@ fi - # structures (such as rlimit64) without declaring them. As a - # work-around, disable LFS on such configurations - --use_lfs=yes -+use_lfs=no - AC_MSG_CHECKING(Solaris LFS bug) - AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ - #define _LARGEFILE_SOURCE 1 -diff -Naurp Python-2.7.15.orig/Modules/mmapmodule.c Python-2.7.15/Modules/mmapmodule.c ---- Python-2.7.15.orig/Modules/mmapmodule.c 2018-04-30 00:47:33.000000000 +0200 -+++ Python-2.7.15/Modules/mmapmodule.c 2018-07-05 16:18:40.953035027 +0200 -@@ -78,6 +78,12 @@ my_getpagesize(void) - # define MAP_ANONYMOUS MAP_ANON - #endif - -+//PMPP API<21 -+#if defined(__ANDROID_API__) && __ANDROID_API__ < 21 -+ extern void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset); -+#endif -+//PMPP API<21 -+ - static PyObject *mmap_module_error; - - typedef enum -diff -Naurp Python-2.7.15.orig/Modules/posixmodule.c Python-2.7.15/Modules/posixmodule.c ---- Python-2.7.15.orig/Modules/posixmodule.c 2018-04-30 00:47:33.000000000 +0200 -+++ Python-2.7.15/Modules/posixmodule.c 2018-07-05 16:20:48.933033807 +0200 -@@ -9477,6 +9477,12 @@ all_ins(PyObject *d) - #define MODNAME "posix" - #endif - -+//PMPP API<21 -+#if defined(__ANDROID_API__) && __ANDROID_API__ < 21 -+ extern ssize_t sendfile(int out_fd, int in_fd, off_t *offset, size_t count); -+#endif -+//PMPP API<21 -+ - PyMODINIT_FUNC - INITFUNC(void) - { -diff -Naurp Python-2.7.15.orig/Modules/signalmodule.c Python-2.7.15/Modules/signalmodule.c ---- Python-2.7.15.orig/Modules/signalmodule.c 2018-04-30 00:47:33.000000000 +0200 -+++ Python-2.7.15/Modules/signalmodule.c 2018-07-05 16:40:46.601022385 +0200 -@@ -32,6 +32,13 @@ - #include - #endif - -+//PMPP API<21 -+#if defined(__ANDROID_API__) && __ANDROID_API__ < 21 -+ #define SIGRTMIN 32 -+ #define SIGRTMAX _NSIG -+#endif -+//PMPP API<21 -+ - #ifndef NSIG - # if defined(_NSIG) - # define NSIG _NSIG /* For BSD/SysV */ -diff -Naurp Python-2.7.15.orig/Modules/termios.c Python-2.7.15/Modules/termios.c ---- Python-2.7.15.orig/Modules/termios.c 2018-04-30 00:47:33.000000000 +0200 -+++ Python-2.7.15/Modules/termios.c 2018-07-05 16:43:16.457020956 +0200 -@@ -357,7 +357,11 @@ static struct constant { - #endif - - /* tcsetattr() constants */ -+#if defined(__ANDROID_API__) && __ANDROID_API__ > 0 -+ {"TCSANOW", TCSETS}, // https://github.com/android-ndk/ndk/issues/441 -+#else - {"TCSANOW", TCSANOW}, -+#endif - {"TCSADRAIN", TCSADRAIN}, - {"TCSAFLUSH", TCSAFLUSH}, - #ifdef TCSASOFT -diff -Naurp Python-2.7.15.orig/Objects/obmalloc.c Python-2.7.15/Objects/obmalloc.c ---- Python-2.7.15.orig/Objects/obmalloc.c 2018-04-30 00:47:33.000000000 +0200 -+++ Python-2.7.15/Objects/obmalloc.c 2018-07-05 16:52:27.577015700 +0200 -@@ -1,5 +1,11 @@ - #include "Python.h" - -+//PMPP API<21 -+#if __ANDROID_API__ < 21 -+ extern void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset); -+#endif -+//PMPP API<21 -+ - #if defined(__has_feature) /* Clang */ - #if __has_feature(address_sanitizer) /* is ASAN enabled? */ - #define ATTRIBUTE_NO_ADDRESS_SAFETY_ANALYSIS \ -############################################################### -######### ANDROID LOCALE PATCHES FOR ANDROID API < 21 ######### -############################################################### ---- Python-2.7.15.orig/Modules/_localemodule.c 2018-04-30 00:47:33.000000000 +0200 -+++ Python-2.7.15/Modules/_localemodule.c 2018-07-05 16:39:08.241023323 +0200 -@@ -170,6 +170,12 @@ PyLocale_setlocale(PyObject* self, PyObj - PyErr_SetString(Error, "invalid locale category"); - return NULL; - } -+#else -+ #ifdef __ANDROID__ -+ #if defined(__ANDROID_API__) && __ANDROID_API__ < 20 -+ return PyUnicode_FromFormat("%s", "C"); -+ #endif -+ #endif - #endif - - if (locale) { -@@ -215,7 +221,15 @@ PyLocale_localeconv(PyObject* self) - return NULL; - - /* if LC_NUMERIC is different in the C library, use saved value */ -- l = localeconv(); -+ //PMPP API<21 -+ #if defined(__ANDROID_API__) && __ANDROID_API__ < 21 -+ /* Don't even try on Android's broken locale.h. */ -+ goto failed; -+ #else -+ /* if LC_NUMERIC is different in the C library, use saved value */ -+ l = localeconv(); //PATCHED -+ #endif -+ //PMPP API<21 - - /* hopefully, the localeconv result survives the C library calls - involved herein */ -@@ -215,7 +215,11 @@ PyLocale_localeconv(PyObject* self) - return NULL; - - /* if LC_NUMERIC is different in the C library, use saved value */ -+#if defined(__ANDROID_API__) && __ANDROID_API__ >= 21 - l = localeconv(); -+#else -+ decimal_point = "."; -+#endif - - /* hopefully, the localeconv result survives the C library calls - involved herein */ ---- Python-2.7.15/Objects/stringlib/formatter.h.orig 2018-04-30 00:47:33.000000000 +0200 -+++ Python-2.7.15/Objects/stringlib/formatter.h 2018-12-26 11:37:08.771315390 +0100 -@@ -640,11 +640,17 @@ get_locale_info(int type, LocaleInfo *lo - { - switch (type) { - case LT_CURRENT_LOCALE: { -+#if defined(__ANDROID_API__) && __ANDROID_API__ >= 21 -+/* NDK version for SDK below 21 doesn't implement the whole C++11 standard in -+ the STL. locale.h header has stubs for localeconv() method, but the library -+ doesn't implement it. The closest Android SDK that implement localeconv() -+ is SDK 21*/ - struct lconv *locale_data = localeconv(); - locale_info->decimal_point = locale_data->decimal_point; - locale_info->thousands_sep = locale_data->thousands_sep; - locale_info->grouping = locale_data->grouping; - break; -+#endif - } - case LT_DEFAULT_LOCALE: - locale_info->decimal_point = "."; ---- Python-2.7.15/Objects/stringlib/localeutil.h.orig 2018-04-30 00:47:33.000000000 +0200 -+++ Python-2.7.15/Objects/stringlib/localeutil.h 2018-12-26 11:38:10.003314806 +0100 -@@ -202,9 +202,18 @@ _Py_InsertThousandsGroupingLocale(STRING - Py_ssize_t n_digits, - Py_ssize_t min_width) - { -+#if defined(__ANDROID_API__) && __ANDROID_API__ >= 21 -+/* NDK version for SDK below 21 doesn't implement the whole C++11 standard in -+ the STL. locale.h header has stubs for localeconv() method, but the library -+ doesn't implement it. The closest Android SDK that implement localeconv() -+ is SDK 21*/ - struct lconv *locale_data = localeconv(); - const char *grouping = locale_data->grouping; - const char *thousands_sep = locale_data->thousands_sep; -+#else -+ const char *grouping = "\3\0"; -+ const char *thousands_sep = ","; -+#endif - - return _Py_InsertThousandsGrouping(buffer, n_buffer, digits, n_digits, - min_width, grouping, thousands_sep); ---- Python-2.7.15/Python/pystrtod.c.orig 2018-04-30 00:47:33.000000000 +0200 -+++ Python-2.7.15/Python/pystrtod.c 2018-12-26 11:47:54.723309229 +0100 -@@ -126,7 +126,13 @@ _PyOS_ascii_strtod(const char *nptr, cha - { - char *fail_pos; - double val = -1.0; -+#if defined(__ANDROID_API__) && __ANDROID_API__ >= 21 -+/* NDK version for SDK below 21 doesn't implement the whole C++11 standard in -+ the STL. locale.h header has stubs for localeconv() method, but the library -+ doesn't implement it. The closest Android SDK that implement localeconv() -+ is SDK 21*/ - struct lconv *locale_data; -+#endif - const char *decimal_point; - size_t decimal_point_len; - const char *p, *decimal_point_pos; -@@ -138,8 +144,16 @@ _PyOS_ascii_strtod(const char *nptr, cha - - fail_pos = NULL; - -+#if defined(__ANDROID_API__) && __ANDROID_API__ >= 21 -+/* NDK version for SDK below 21 doesn't implement the whole C++11 standard in -+ the STL. locale.h header has stubs for localeconv() method, but the library -+ doesn't implement it. The closest Android SDK that implement localeconv() -+ is SDK 21*/ - locale_data = localeconv(); - decimal_point = locale_data->decimal_point; -+#else -+ decimal_point = "."; -+#endif - decimal_point_len = strlen(decimal_point); - - assert(decimal_point_len != 0); -@@ -375,8 +389,16 @@ PyOS_string_to_double(const char *s, - Py_LOCAL_INLINE(void) - change_decimal_from_locale_to_dot(char* buffer) - { -+#if defined(__ANDROID_API__) && __ANDROID_API__ >= 21 -+/* NDK version for SDK below 21 doesn't implement the whole C++11 standard in -+ the STL. locale.h header has stubs for localeconv() method, but the library -+ doesn't implement it. The closest Android SDK that implement localeconv() -+ is SDK 21*/ - struct lconv *locale_data = localeconv(); - const char *decimal_point = locale_data->decimal_point; -+#else -+ decimal_point = "."; -+#endif - - if (decimal_point[0] != '.' || decimal_point[1] != 0) { - size_t decimal_point_len = strlen(decimal_point); diff --git a/pythonforandroid/recipes/python2/patches/fix-ctypes-util-find-library.patch b/pythonforandroid/recipes/python2/patches/fix-ctypes-util-find-library.patch deleted file mode 100644 index 4f29b047ad..0000000000 --- a/pythonforandroid/recipes/python2/patches/fix-ctypes-util-find-library.patch +++ /dev/null @@ -1,19 +0,0 @@ -diff -u a/Lib/ctypes/util.py b/Lib/ctypes/util.py ---- a/Lib/ctypes/util.py 2019-06-20 18:52:01.372205226 +0200 -+++ b/Lib/ctypes/util.py 2019-06-20 18:51:39.612970779 +0200 -@@ -70,7 +70,14 @@ - def find_library(name): - return name - --if os.name == "posix" and sys.platform == "darwin": -+# This patch overrides the find_library to look in the right places on -+# Android -+if True: -+ from android._ctypes_library_finder import find_library as _find_lib -+ def find_library(name): -+ return _find_lib(name) -+ -+elif os.name == "posix" and sys.platform == "darwin": - from ctypes.macholib.dyld import dyld_find as _dyld_find - def find_library(name): - possible = ['lib%s.dylib' % name, diff --git a/pythonforandroid/recipes/python2/patches/fix-filesystem-default-encoding.patch b/pythonforandroid/recipes/python2/patches/fix-filesystem-default-encoding.patch deleted file mode 100644 index 7cf1a8f860..0000000000 --- a/pythonforandroid/recipes/python2/patches/fix-filesystem-default-encoding.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- Python-2.7.15.orig/Python/bltinmodule.c 2017-12-29 01:44:57.018079845 +0200 -+++ Python-2.7.15/Python/bltinmodule.c 2017-12-29 01:45:02.650079649 +0200 -@@ -22,7 +22,7 @@ - #elif defined(__APPLE__) - const char *Py_FileSystemDefaultEncoding = "utf-8"; - #else --const char *Py_FileSystemDefaultEncoding = NULL; /* use default */ -+const char *Py_FileSystemDefaultEncoding = "utf-8"; /* use default */ - #endif - - /* Forward */ diff --git a/pythonforandroid/recipes/python2/patches/fix-gethostbyaddr.patch b/pythonforandroid/recipes/python2/patches/fix-gethostbyaddr.patch deleted file mode 100644 index a3824f4348..0000000000 --- a/pythonforandroid/recipes/python2/patches/fix-gethostbyaddr.patch +++ /dev/null @@ -1,12 +0,0 @@ ---- Python-2.7.15/Modules/socketmodule.c.orig 2017-12-29 01:40:09.915694810 +0100 -+++ Python-2.7.15/Modules/socketmodule.c 2017-12-29 01:40:36.967694486 +0100 -@@ -156,6 +156,9 @@ - On the other hand, not all Linux versions agree, so there the settings - computed by the configure script are needed! */ - -+/* Android hack, same reason are what is described above */ -+#undef HAVE_GETHOSTBYNAME_R -+ - #ifndef linux - # undef HAVE_GETHOSTBYNAME_R_3_ARG - # undef HAVE_GETHOSTBYNAME_R_5_ARG diff --git a/pythonforandroid/recipes/python2/patches/fix-interpreter-version.patch b/pythonforandroid/recipes/python2/patches/fix-interpreter-version.patch deleted file mode 100644 index a1828bf582..0000000000 --- a/pythonforandroid/recipes/python2/patches/fix-interpreter-version.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- Python-2.7.15/configure.orig 2018-04-30 00:47:33.000000000 +0200 -+++ Python-2.7.15/configure 2019-08-16 14:09:48.696030207 +0200 -@@ -2903,7 +2903,7 @@ case $host_os in *\ *) host_os=`echo "$h - # pybuilddir.txt will be created by --generate-posix-vars in the Makefile - rm -f pybuilddir.txt - --for ac_prog in python$PACKAGE_VERSION python3 python -+for ac_prog in python$PACKAGE_VERSION python2 python - do - # Extract the first word of "$ac_prog", so it can be a program name with args. - set dummy $ac_prog; ac_word=$2 diff --git a/pythonforandroid/recipes/python2/patches/fix-missing-extensions.patch b/pythonforandroid/recipes/python2/patches/fix-missing-extensions.patch deleted file mode 100644 index cb777d3b1f..0000000000 --- a/pythonforandroid/recipes/python2/patches/fix-missing-extensions.patch +++ /dev/null @@ -1,108 +0,0 @@ -diff -Naurp Python-2.7.15.orig/Makefile.pre.in Python-2.7.15/Makefile.pre.in ---- Python-2.7.15.orig/Makefile.pre.in 2018-04-30 00:47:33.000000000 +0200 -+++ Python-2.7.15/Makefile.pre.in 2018-11-18 00:43:58.777379280 +0100 -@@ -20,6 +20,7 @@ - - # === Variables set by makesetup === - -+MODNAMES= _MODNAMES_ - MODOBJS= _MODOBJS_ - MODLIBS= _MODLIBS_ - -diff -Naurp Python-2.7.15.orig/Modules/_ctypes/libffi/src/arm/sysv.S Python-2.7.15/Modules/_ctypes/libffi/src/arm/sysv.S ---- Python-2.7.15.orig/Modules/_ctypes/libffi/src/arm/sysv.S 2018-04-30 00:47:33.000000000 +0200 -+++ Python-2.7.15/Modules/_ctypes/libffi/src/arm/sysv.S 2018-11-17 22:28:50.925456603 +0100 -@@ -396,7 +396,7 @@ LSYM(Lbase_args): - beq LSYM(Lepilogue_vfp) - - cmp r3, #FFI_TYPE_SINT64 -- stmeqia r2, {r0, r1} -+ stmiaeq r2, {r0, r1} - beq LSYM(Lepilogue_vfp) - - cmp r3, #FFI_TYPE_FLOAT -diff -Naurp Python-2.7.15.orig/Modules/makesetup Python-2.7.15/Modules/makesetup ---- Python-2.7.15.orig/Modules/makesetup 2018-04-30 00:47:33.000000000 +0200 -+++ Python-2.7.15/Modules/makesetup 2018-11-18 00:43:10.289379743 +0100 -@@ -110,6 +110,7 @@ sed -e 's/[ ]*#.*//' -e '/^[ ]*$/d' | - # Rules appended by makedepend - " >$rulesf - DEFS= -+ NAMES= - MODS= - SHAREDMODS= - OBJS= -@@ -181,7 +182,7 @@ sed -e 's/[ ]*#.*//' -e '/^[ ]*$/d' | - *.*) echo 1>&2 "bad word $arg in $line" - exit 1;; - -u) skip=libs; libs="$libs -u";; -- [a-zA-Z_]*) mods="$mods $arg";; -+ [a-zA-Z_]*) NAMES="$NAMES $arg"; mods="$mods $arg";; - *) echo 1>&2 "bad word $arg in $line" - exit 1;; - esac -@@ -284,6 +285,7 @@ sed -e 's/[ ]*#.*//' -e '/^[ ]*$/d' | - echo "1i\\" >$sedf - str="# Generated automatically from $makepre by makesetup." - echo "$str" >>$sedf -+ echo "s%_MODNAMES_%$NAMES%" >>$sedf - echo "s%_MODOBJS_%$OBJS%" >>$sedf - echo "s%_MODLIBS_%$LIBS%" >>$sedf - echo "/Definitions added by makesetup/a$NL$NL$DEFS" >>$sedf -diff -Naurp Python-2.7.15.orig/setup.py Python-2.7.15/setup.py ---- Python-2.7.15.orig/setup.py 2018-04-30 00:47:33.000000000 +0200 -+++ Python-2.7.15/setup.py 2018-11-18 00:40:50.021381080 +0100 -@@ -217,7 +217,11 @@ class PyBuildExt(build_ext): - # Python header files - headers = [sysconfig.get_config_h_filename()] - headers += glob(os.path.join(sysconfig.get_path('include'), "*.h")) -- for ext in self.extensions[:]: -+ # The sysconfig variable built by makesetup, listing the already -+ # built modules as configured by the Setup files. -+ modnames = sysconfig.get_config_var('MODNAMES').split() -+ removed_modules = [] -+ for ext in self.extensions: - ext.sources = [ find_module_file(filename, moddirlist) - for filename in ext.sources ] - if ext.depends is not None: -@@ -231,10 +235,10 @@ class PyBuildExt(build_ext): - # platform specific include directories - ext.include_dirs.extend(incdirlist) - -- # If a module has already been built statically, -- # don't build it here -- if ext.name in sys.builtin_module_names: -- self.extensions.remove(ext) -+ # If a module has already been built by the Makefile, -+ # don't build it here. -+ if ext.name in modnames: -+ removed_modules.append(ext) - - # Parse Modules/Setup and Modules/Setup.local to figure out which - # modules are turned on in the file. -@@ -249,8 +253,9 @@ class PyBuildExt(build_ext): - input.close() - - for ext in self.extensions[:]: -- if ext.name in remove_modules: -- self.extensions.remove(ext) -+ if removed_modules: -+ self.extensions = [x for x in self.extensions if x not in -+ removed_modules] - - # When you run "make CC=altcc" or something similar, you really want - # those environment variables passed into the setup.py phase. Here's -@@ -290,6 +295,13 @@ class PyBuildExt(build_ext): - " detect_modules() for the module's name.") - print - -+ if removed_modules: -+ print("The following modules found by detect_modules() in" -+ " setup.py, have been") -+ print("built by the Makefile instead, as configured by the" -+ " Setup files:") -+ print_three_column([ext.name for ext in removed_modules]) -+ - if self.failed: - failed = self.failed[:] - print diff --git a/pythonforandroid/recipes/python2/patches/fix-posix-declarations.patch b/pythonforandroid/recipes/python2/patches/fix-posix-declarations.patch deleted file mode 100644 index c2a80499b9..0000000000 --- a/pythonforandroid/recipes/python2/patches/fix-posix-declarations.patch +++ /dev/null @@ -1,24 +0,0 @@ ---- Python-2.7.15/Modules/posixmodule.c.orig 2018-04-30 00:47:33.000000000 +0200 -+++ Python-2.7.15/Modules/posixmodule.c 2018-12-26 13:46:37.307241303 +0100 -@@ -35,6 +35,12 @@ - # include - #endif /* defined(__VMS) */ - -+/* On android API level 21, 'AT_EACCESS' is not declared although -+ * HAVE_FACCESSAT is defined. */ -+#ifdef __ANDROID__ -+#undef HAVE_FACCESSAT -+#endif -+ - #ifdef __cplusplus - extern "C" { - #endif -@@ -3991,7 +3997,7 @@ posix_openpty(PyObject *self, PyObject * - slave_fd = open(slave_name, O_RDWR | O_NOCTTY); /* open slave */ - if (slave_fd < 0) - return posix_error(); --#if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC) -+#if !defined(__CYGWIN__) && !defined(__ANDROID__) && !defined(HAVE_DEV_PTC) - ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */ - ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */ - #ifndef __hpux diff --git a/pythonforandroid/recipes/python2/patches/fix-pwd-gecos.patch b/pythonforandroid/recipes/python2/patches/fix-pwd-gecos.patch deleted file mode 100644 index cdc06fd4ad..0000000000 --- a/pythonforandroid/recipes/python2/patches/fix-pwd-gecos.patch +++ /dev/null @@ -1,89 +0,0 @@ ---- Python-2.7.15/configure.orig 2018-04-30 00:47:33.000000000 +0200 -+++ Python-2.7.15/configure 2018-12-26 12:46:08.163275913 +0100 -@@ -12177,6 +12177,32 @@ _ACEOF - - fi - -+ac_fn_c_check_member "$LINENO" "struct passwd" "pw_gecos" "ac_cv_member_struct_passwd_pw_gecos" " -+ #include -+ #include -+ -+" -+if test "x$ac_cv_member_struct_passwd_pw_gecos" = xyes; then : -+ -+cat >>confdefs.h <<_ACEOF -+#define HAVE_STRUCT_PASSWD_PW_GECOS 1 -+_ACEOF -+ -+ -+fi -+ac_fn_c_check_member "$LINENO" "struct passwd" "pw_passwd" "ac_cv_member_struct_passwd_pw_passwd" " -+ #include -+ #include -+ -+" -+if test "x$ac_cv_member_struct_passwd_pw_passwd" = xyes; then : -+ -+cat >>confdefs.h <<_ACEOF -+#define HAVE_STRUCT_PASSWD_PW_PASSWD 1 -+_ACEOF -+ -+ -+fi - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for time.h that defines altzone" >&5 - $as_echo_n "checking for time.h that defines altzone... " >&6; } ---- Python-2.7.15/configure.ac.orig 2018-04-30 00:47:33.000000000 +0200 -+++ Python-2.7.15/configure.ac 2018-12-26 12:50:20.679273505 +0100 -@@ -3562,6 +3562,10 @@ AC_CHECK_MEMBERS([struct stat.st_flags]) - AC_CHECK_MEMBERS([struct stat.st_gen]) - AC_CHECK_MEMBERS([struct stat.st_birthtime]) - AC_CHECK_MEMBERS([struct stat.st_blocks]) -+AC_CHECK_MEMBERS([struct passwd.pw_gecos, struct passwd.pw_passwd], [], [], [[ -+ #include -+ #include -+]]) - - AC_MSG_CHECKING(for time.h that defines altzone) - AC_CACHE_VAL(ac_cv_header_time_altzone,[ ---- Python-2.7.15/pyconfig.h.in.orig 2018-04-30 00:47:33.000000000 +0200 -+++ Python-2.7.15/pyconfig.h.in 2018-12-26 12:52:13.247272432 +0100 -@@ -737,6 +737,12 @@ - /* Define to 1 if you have the header file. */ - #undef HAVE_STROPTS_H - -+/* Define to 1 if `pw_gecos' is a member of `struct passwd'. */ -+#undef HAVE_STRUCT_PASSWD_PW_GECOS -+ -+/* Define to 1 if `pw_passwd' is a member of `struct passwd'. */ -+#undef HAVE_STRUCT_PASSWD_PW_PASSWD -+ - /* Define to 1 if `st_birthtime' is a member of `struct stat'. */ - #undef HAVE_STRUCT_STAT_ST_BIRTHTIME - ---- Python-2.7.15/Modules/pwdmodule.c.orig 2018-04-30 00:47:33.000000000 +0200 -+++ Python-2.7.15/Modules/pwdmodule.c 2018-12-26 12:38:47.611280115 +0100 -@@ -68,17 +68,17 @@ mkpwent(struct passwd *p) - #define SETS(i,val) sets(v, i, val) - - SETS(setIndex++, p->pw_name); --#ifdef __VMS -- SETS(setIndex++, ""); --#else -+#if defined(HAVE_STRUCT_PASSWD_PW_PASSWD) - SETS(setIndex++, p->pw_passwd); -+#else -+ SETS(setIndex++, ""); - #endif - PyStructSequence_SET_ITEM(v, setIndex++, _PyInt_FromUid(p->pw_uid)); - PyStructSequence_SET_ITEM(v, setIndex++, _PyInt_FromGid(p->pw_gid)); --#ifdef __VMS -- SETS(setIndex++, ""); --#else -+#if defined(HAVE_STRUCT_PASSWD_PW_GECOS) - SETS(setIndex++, p->pw_gecos); -+#else -+ SETS(setIndex++, ""); - #endif - SETS(setIndex++, p->pw_dir); - SETS(setIndex++, p->pw_shell); diff --git a/pythonforandroid/recipes/python2/patches/fix-zlib-version.patch b/pythonforandroid/recipes/python2/patches/fix-zlib-version.patch deleted file mode 100644 index b7c14dbf80..0000000000 --- a/pythonforandroid/recipes/python2/patches/fix-zlib-version.patch +++ /dev/null @@ -1,12 +0,0 @@ ---- Python-3.7.1/setup.py.orig 2018-10-20 08:04:19.000000000 +0200 -+++ Python-3.7.1/setup.py 2019-02-17 00:24:30.715904412 +0100 -@@ -1416,7 +1416,8 @@ class PyBuildExt(build_ext): - if zlib_inc is not None: - zlib_h = zlib_inc[0] + '/zlib.h' - version = '"0.0.0"' -- version_req = '"1.1.3"' -+ version_req = '"{}"'.format( -+ os.environ.get('ZLIB_VERSION', '1.1.3')) - if host_platform == 'darwin' and is_macosx_sdk_path(zlib_h): - zlib_h = os.path.join(macosx_sdk_root(), zlib_h[1:]) - with open(zlib_h) as fp: diff --git a/pythonforandroid/recipes/python3/__init__.py b/pythonforandroid/recipes/python3/__init__.py index c80875ccc3..8a84d510f0 100644 --- a/pythonforandroid/recipes/python3/__init__.py +++ b/pythonforandroid/recipes/python3/__init__.py @@ -58,7 +58,6 @@ class Python3Recipe(GuestPythonRecipe): # - _bz2.so # - _lzma.so opt_depends = ['libbz2', 'liblzma'] - conflicts = ['python2'] configure_args = ( '--host={android_host}', diff --git a/pythonforandroid/recipes/secp256k1/__init__.py b/pythonforandroid/recipes/secp256k1/__init__.py index 338c7b90c3..fc7c7050cd 100644 --- a/pythonforandroid/recipes/secp256k1/__init__.py +++ b/pythonforandroid/recipes/secp256k1/__init__.py @@ -11,8 +11,8 @@ class Secp256k1Recipe(CppCompiledComponentsPythonRecipe): depends = [ 'openssl', - ('hostpython3', 'hostpython2'), - ('python2', 'python3'), + 'hostpython3', + 'python3', 'setuptools', 'libffi', 'cffi', diff --git a/pythonforandroid/recipes/shapely/__init__.py b/pythonforandroid/recipes/shapely/__init__.py index f70876132e..7e44d40db2 100644 --- a/pythonforandroid/recipes/shapely/__init__.py +++ b/pythonforandroid/recipes/shapely/__init__.py @@ -7,11 +7,6 @@ class ShapelyRecipe(CythonRecipe): url = 'https://github.com/Toblerity/Shapely/archive/{version}.tar.gz' depends = ['setuptools', 'libgeos'] - # Actually, this recipe seems to compile/install fine for python2, but it - # fails at runtime when importing module with: - # `[Errno 2] No such file or directory` - conflicts = ['python2'] - call_hostpython_via_targetpython = False # Patch to avoid libgeos check (because it fails), insert environment diff --git a/pythonforandroid/recommendations.py b/pythonforandroid/recommendations.py index 163e4ae6d5..9f5cd36dc2 100644 --- a/pythonforandroid/recommendations.py +++ b/pythonforandroid/recommendations.py @@ -194,10 +194,8 @@ def check_ndk_api(ndk_api, android_api): minor=MIN_PYTHON_MINOR_VERSION)) PY2_ERROR_TEXT = ( 'python-for-android no longer supports running under Python 2. Either upgrade to ' - 'Python {min_version} or higher (recommended), or revert to python-for-android 2019.07.08. ' - 'Note that you *can* still target Python 2 on Android by including python2 in your ' - 'requirements.').format( - min_version=MIN_PYTHON_VERSION) + 'Python {min_version} or higher (recommended), or revert to python-for-android 2019.07.08.' +).format(min_version=MIN_PYTHON_VERSION) PY_VERSION_ERROR_TEXT = ( 'Your Python version {user_major}.{user_minor} is not supported by python-for-android, ' diff --git a/pythonforandroid/toolchain.py b/pythonforandroid/toolchain.py index adb46acdf0..b4236d8860 100644 --- a/pythonforandroid/toolchain.py +++ b/pythonforandroid/toolchain.py @@ -749,7 +749,7 @@ def recipes(self, args): .. code-block:: bash python3 3.7.1 depends: ['hostpython3', 'sqlite3', 'openssl', 'libffi'] - conflicts: ['python2'] + conflicts: [] optional depends: ['sqlite3', 'libffi', 'openssl'] """ ctx = self.ctx diff --git a/pythonforandroid/tools/liblink b/pythonforandroid/tools/liblink index 69f8ef23af..182eff7a6c 100755 --- a/pythonforandroid/tools/liblink +++ b/pythonforandroid/tools/liblink @@ -1,4 +1,4 @@ -#!/usr/bin/env python2.7 +#!/usr/bin/env python from __future__ import print_function import sys diff --git a/testapps/setup_testapp_python2.py b/testapps/setup_testapp_python2.py deleted file mode 100644 index 9499c80c73..0000000000 --- a/testapps/setup_testapp_python2.py +++ /dev/null @@ -1,32 +0,0 @@ - -from distutils.core import setup -from setuptools import find_packages - -options = {'apk': {'requirements': 'sdl2,numpy,pyjnius,kivy,python2', - 'android-api': 27, - 'ndk-api': 21, - 'ndk-dir': '/home/asandy/android/android-ndk-r17c', - 'dist-name': 'bdisttest_python2', - 'ndk-version': '10.3.2', - 'permission': 'VIBRATE', - 'arch': 'armeabi-v7a', - 'window': None, - }} - -package_data = {'': ['*.py', - '*.png'] - } - -packages = find_packages() -print('packages are', packages) - -setup( - name='testapp_python2', - version='1.1', - description='p4a setup.py test', - author='Alexander Taylor', - author_email='alexanderjohntaylor@gmail.com', - packages=find_packages(), - options=options, - package_data={'testapp': ['*.py', '*.png']} -) diff --git a/testapps/setup_testapp_python2_sqlite_openssl.py b/testapps/setup_testapp_python2_sqlite_openssl.py deleted file mode 100644 index c1dcf53efc..0000000000 --- a/testapps/setup_testapp_python2_sqlite_openssl.py +++ /dev/null @@ -1,25 +0,0 @@ - -from distutils.core import setup -from setuptools import find_packages - -options = {'apk': {'requirements': 'sdl2,pyjnius,kivy,python2,openssl,requests,peewee,sqlite3', - 'android-api': 27, - 'ndk-api': 21, - 'ndk-dir': '/home/sandy/android/android-ndk-r17c', - 'dist-name': 'bdisttest_python2_sqlite_openssl', - 'ndk-version': '10.3.2', - 'permissions': ['INTERNET', 'VIBRATE'], - 'arch': 'armeabi-v7a', - 'window': None, - }} - -setup( - name='testapp_python2_sqlite_openssl', - version='1.1', - description='p4a setup.py test', - author='Alexander Taylor', - author_email='alexanderjohntaylor@gmail.com', - packages=find_packages(), - options=options, - package_data={'testapp_sqlite_openssl': ['*.py', '*.png']} -) diff --git a/testapps/testlauncher_setup/sdl2.py b/testapps/testlauncher_setup/sdl2.py index 9db55dc497..11f1a3785a 100644 --- a/testapps/testlauncher_setup/sdl2.py +++ b/testapps/testlauncher_setup/sdl2.py @@ -5,7 +5,7 @@ 'bootstrap': 'sdl2', 'launcher': None, 'requirements': ( - 'python2,sdl2,android,' + 'python3,sdl2,android,' 'sqlite3,docutils,pygments,kivy,pyjnius,plyer,' 'cymunk,lxml,pil,openssl,pyopenssl,' 'twisted'), # audiostream, ffmpeg, numpy diff --git a/tests/test_bootstrap.py b/tests/test_bootstrap.py index aa84fba446..ca0db9aee5 100644 --- a/tests/test_bootstrap.py +++ b/tests/test_bootstrap.py @@ -76,7 +76,7 @@ def test_attributes(self): bs = Bootstrap().get_bootstrap("sdl2", self.ctx) self.assertEqual(bs.name, "sdl2") self.assertEqual(bs.jni_dir, "sdl2/jni") - self.assertEqual(bs.get_build_dir_name(), "sdl2-python3") + self.assertEqual(bs.get_build_dir_name(), "sdl2") # bs.dist_dir should raise an error if there is no distribution to query bs.distribution = None @@ -100,7 +100,7 @@ def test_build_dist_dirs(self): bs = Bootstrap.get_bootstrap("sdl2", self.ctx) self.assertTrue( - bs.get_build_dir().endswith("build/bootstrap_builds/sdl2-python3") + bs.get_build_dir().endswith("build/bootstrap_builds/sdl2") ) self.assertTrue(bs.get_dist_dir("test_prj").endswith("dists/test_prj")) self.assertTrue( @@ -181,8 +181,8 @@ def test_expand_dependencies_with_pure_python_package(self): expanded_result = expand_dependencies( ["python3", "kivy", "peewee"], self.ctx ) - # we expect to have two results (one for python2 and one for python3) - self.assertEqual(len(expanded_result), 2) + # we expect to one results for python3 + self.assertEqual(len(expanded_result), 1) self.assertIsInstance(expanded_result, list) for i in expanded_result: self.assertIsInstance(i, list) @@ -244,11 +244,6 @@ def _add_sdl2_conflicting_recipe(name, ctx): ) self.assertEqual(bs.name, "service_only") - # Test wrong recipes - wrong_recipes = {"python2", "python3", "pyjnius"} - bs = Bootstrap.get_bootstrap_from_recipes(wrong_recipes, self.ctx) - self.assertIsNone(bs) - @mock.patch("pythonforandroid.bootstrap.ensure_dir") def test_prepare_dist_dir(self, mock_ensure_dir): """A test which will initialize a bootstrap and will check if the diff --git a/tests/test_entrypoints_python2.py b/tests/test_entrypoints_python2.py deleted file mode 100644 index 0a2f6ebb4f..0000000000 --- a/tests/test_entrypoints_python2.py +++ /dev/null @@ -1,38 +0,0 @@ - -# This test is a special case that we expect to run under Python 2, so -# include the necessary compatibility imports: -try: # Python 3 - from unittest import mock -except ImportError: # Python 2 - import mock - -from pythonforandroid.recommendations import PY2_ERROR_TEXT -from pythonforandroid import entrypoints - - -def test_main_python2(): - """Test that running under Python 2 leads to the build failing, while - running under a suitable version works fine. - - Note that this test must be run *using* Python 2 to truly test - that p4a can reach the Python version check before importing some - Python-3-only syntax and crashing. - """ - - # Under Python 2, we should get a normal control flow exception - # that is handled properly, not any other type of crash - handle_exception_path = 'pythonforandroid.entrypoints.handle_build_exception' - with mock.patch('sys.version_info') as fake_version_info, \ - mock.patch(handle_exception_path) as handle_build_exception: # noqa: E127 - - fake_version_info.major = 2 - fake_version_info.minor = 7 - - def check_python2_exception(exc): - """Check that the exception message is Python 2 specific.""" - assert exc.message == PY2_ERROR_TEXT - handle_build_exception.side_effect = check_python2_exception - - entrypoints.main() - - handle_build_exception.assert_called_once() diff --git a/tests/test_graph.py b/tests/test_graph.py index ebe9fb400d..9cc44fc041 100644 --- a/tests/test_graph.py +++ b/tests/test_graph.py @@ -13,7 +13,7 @@ ctx = Context() -name_sets = [['python2'], +name_sets = [['python3'], ['kivy']] bootstraps = [None, Bootstrap.get_bootstrap('sdl2', ctx)] @@ -26,7 +26,7 @@ ] ) invalid_combinations = [ - [['python2', 'python3'], None], + [['pil', 'pillow'], None], [['pysdl2', 'genericndkbuild'], None], ] invalid_combinations_simple = list(invalid_combinations) @@ -211,7 +211,7 @@ def test_multichoice_obvious_conflict_checker(monkeypatch): def test_bootstrap_dependency_addition(): build_order, python_modules, bs = get_recipe_order_and_bootstrap( ctx, ['kivy'], None) - assert (('hostpython2' in build_order) or ('hostpython3' in build_order)) + assert ('hostpython3' in build_order) def test_graph_deplist_transformation(): @@ -227,8 +227,8 @@ def test_graph_deplist_transformation(): def test_bootstrap_dependency_addition2(): build_order, python_modules, bs = get_recipe_order_and_bootstrap( - ctx, ['kivy', 'python2'], None) - assert 'hostpython2' in build_order + ctx, ['kivy', 'python3'], None) + assert 'hostpython3' in build_order if __name__ == "__main__": diff --git a/tox.ini b/tox.ini index 6a90ef435d..9ded48b328 100644 --- a/tox.ini +++ b/tox.ini @@ -1,10 +1,9 @@ [tox] -envlist = pep8,py27,py3 +envlist = pep8,py3 basepython = python3 [testenv] deps = - py27: mock pytest virtualenv py3: coveralls @@ -16,12 +15,6 @@ passenv = TRAVIS TRAVIS_* setenv = PYTHONPATH={toxinidir} -[testenv:py27] -# Note that the set of tests is not posargs-configurable here: we only -# check a minimal set of Python 2 tests for the remaining Python 2 -# functionality that we support -commands = pytest tests/test_androidmodule_ctypes_finder.py tests/test_entrypoints_python2.py - [testenv:py3] # for py3 env we will get code coverage commands =