Skip to content

Release 2020.06.02 #2225

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 62 commits into from
Jun 2, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
62 commits
Select commit Hold shift + click to select a range
38ba1ad
Fixes python build with macOS venv
AndreMiras Apr 28, 2020
83dc122
Merge pull request #2159 from AndreMiras/feature/fix_macos_venv_build
AndreMiras Apr 29, 2020
36825d7
Get --add-source working for dirs in Gradle builds (#2156)
kollivier Apr 29, 2020
4b6e095
Adding more assets (#2132)
robertpfeiffer Apr 29, 2020
3bdeaca
Removed python2 support mention from README (#2162)
inclement Apr 29, 2020
9dded87
Adds pygame recipe
Oct 28, 2019
d5c672e
Adds macOS install instructions
AndreMiras May 1, 2020
36426f4
Merge pull request #2165 from AndreMiras/feature/documentation_update
AndreMiras May 1, 2020
66f6a34
Merge pull request #2164 from AndreMiras/feature/pygame_recipe
AndreMiras May 1, 2020
1b887be
Bump to SDL2 2.0.10 & extract .java from SDL2 tarball: merge conflict…
inclement May 1, 2020
b6a35e9
Merge pull request #2175 from kivy/release-2020.04.29
inclement May 7, 2020
581c4b4
Narrows some context manager scopes
AndreMiras May 8, 2020
04b8f35
Downgrades to SDL2 2.0.9
AndreMiras May 8, 2020
2808130
Merge pull request #2180 from AndreMiras/feature/downgrade_sdl2_2.0.9
AndreMiras May 8, 2020
eaf4c2f
Post release version bump 2020.04.29.dev0 (#2176)
AndreMiras May 8, 2020
f96356b
Merge pull request #2179 from AndreMiras/feature/narrow_context_manager
AndreMiras May 9, 2020
afa99bb
Updates release documentation
AndreMiras May 7, 2020
c0d3015
Fixes service only unittest loading
AndreMiras May 9, 2020
4fbcefd
Reuse common AssetExtract.java
AndreMiras May 9, 2020
f29262a
Merge pull request #2181 from AndreMiras/feature/service_only_unittes…
AndreMiras May 9, 2020
f3e9222
Merge pull request #2177 from AndreMiras/feature/release_documentatio…
AndreMiras May 9, 2020
c03f0ff
Use common Hardware.java
AndreMiras May 9, 2020
a3b18f1
Moves kamranzafar/ java directory to common/
AndreMiras May 9, 2020
a0b878d
Removes java concurrency/ folder
AndreMiras May 9, 2020
f00d00b
Merge pull request #2184 from AndreMiras/feature/common_kamranzafar_java
AndreMiras May 9, 2020
de7d06a
Merge pull request #2183 from AndreMiras/feature/common_hardware_java
AndreMiras May 9, 2020
9f9a42f
Merge pull request #2182 from AndreMiras/feature/share_asset_extract
AndreMiras May 9, 2020
2604406
Merge pull request #2185 from AndreMiras/feature/delete_unused_java_c…
AndreMiras May 9, 2020
54c9b62
Deletes deprecated renpy Python{Activity,Service}.java
AndreMiras May 9, 2020
d0deae0
Java code linting using PMD 6.23.0
AndreMiras May 10, 2020
0730f6c
Merge pull request #2186 from AndreMiras/feature/removes_deprecated_r…
AndreMiras May 10, 2020
7b27577
Merge pull request #2187 from AndreMiras/feature/java_code_cleaning
AndreMiras May 10, 2020
53722ed
Share PythonUtil.java between bootstraps
AndreMiras May 10, 2020
eeed13c
Merge pull request #2188 from AndreMiras/feature/share_java_python_util
AndreMiras May 10, 2020
2eb0ddf
:bug: Fixes flake8 errors post update
AndreMiras May 11, 2020
c70432d
Merge pull request #2191 from AndreMiras/feature/linter
AndreMiras May 12, 2020
5312595
:hammer: PythonActivityUtil helper for unpacking data
AndreMiras May 10, 2020
0a76c4a
Merge pull request #2189 from AndreMiras/feature/share_unpack_data_ja…
AndreMiras May 12, 2020
535b39d
:white_check_mark: Add initial tests for python3 recipe (#2192)
opacam May 12, 2020
eb11081
:ambulance: Fix `test_should_build` (#2193)
opacam May 13, 2020
5e6e01e
:pencil2: Rename `Hostpython3Recipe` class to camel case (#2194)
opacam May 13, 2020
5448f34
Fix for 'cannot find setuptools module' (#2195)
atom2626 May 13, 2020
5e90f06
:white_check_mark: Add tests for hostpython3 recipe (#2196)
opacam May 16, 2020
8620562
Remove superfluous recipes fixes #1387
rnixx Sep 15, 2019
e4404c8
Merge pull request #2202 from AndreMiras/remove-superfluous-recipes
AndreMiras May 16, 2020
56a6cf1
:books: Troubleshoot SSL error
AndreMiras May 16, 2020
d96d71e
Merge pull request #2205 from AndreMiras/feature/troubleshooting_ssl_…
AndreMiras May 17, 2020
0610d20
:package: Split logic for build modes & debug symbols (#2213)
opacam May 25, 2020
c8c9776
:sparkles: Add `opencv_extras` recipe (#2209)
opacam May 28, 2020
c236ddd
:pencil: Attempt to improve the issue template
AndreMiras May 30, 2020
13a7899
Merge pull request #2217 from AndreMiras/feature/issue_template_update
AndreMiras May 30, 2020
a22231e
:arrow_up: Bumps to Ubuntu 20.04
AndreMiras May 30, 2020
51de0b3
Merge pull request #2218 from AndreMiras/feature/bumps_to_ubuntu_20.04
AndreMiras May 30, 2020
62bda59
:pencil: Updates install and troubleshooting docs
AndreMiras May 30, 2020
a4be492
:arrow_up: Bumps to Cython==0.29.19
AndreMiras May 30, 2020
70251d8
Merge pull request #2219 from AndreMiras/feature/update_install_docs
AndreMiras May 30, 2020
bff8a2a
Merge pull request #2220 from AndreMiras/feature/bump_latest_cython
AndreMiras May 30, 2020
aca3c4b
:arrow_up: Bumps to Gradle 6.4.1
AndreMiras Jun 1, 2020
5affb70
Merge pull request #2222 from AndreMiras/feature/bumps_gradle_version
AndreMiras Jun 2, 2020
f5e0855
:bug: Adds missing requests sub dependencies
AndreMiras May 30, 2020
46d14e9
Merge pull request #2221 from AndreMiras/feature/fix_on_device_tests
AndreMiras Jun 2, 2020
5a32f68
:bookmark: Updates version number to 2020.06.02
AndreMiras Jun 2, 2020
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 18 additions & 15 deletions .github/ISSUE_TEMPLATE.md
Original file line number Diff line number Diff line change
@@ -1,23 +1,24 @@
<!--
The issue tracker is a tool to address bugs.
Please use the Disord community or Stack Overflow for support questions,
The issue tracker is a tool to address bugs NOT a support platform.
Please use the Discord community or Stack Overflow for support questions,
more information at https://github.com/kivy/python-for-android#support

Before opening a new issue, make sure you do the following:
* check that your issue isn't already filed: https://github.com/kivy/python-for-android/issues
* prepare a short, runnable example that reproduces the issue
* make sure to have `log_level = 2` in your `buildozer.spec`
* reproduce the problem with the latest development version (`p4a.branch = master`)
* double-check that the issue is indeed a bug and not a support request
* please use backticks to format code or logs
-->

### Checklist

- [ ] the issue is indeed a bug and not a support request
- [ ] issue doesn't already exist: https://github.com/kivy/python-for-android/issues
- [ ] I have a short, runnable example that reproduces the issue
- [ ] I reproduced the problem with the latest development version (`p4a.branch = develop`)
- [ ] I used the grave accent (aka backticks) to format code or logs when appropriated

### Versions

* Python:
* OS:
* Kivy:
* Cython:
- Python:
- OS:
- Kivy:
- Cython:
- OpenJDK:

### Description

Expand All @@ -28,6 +29,7 @@ Before opening a new issue, make sure you do the following:
Command:
```sh
// REPLACE ME: buildozer command ran? e.g. buildozer android debug
// Keep the triple grave accent (aka backquote/backtick) to have the code formatted
```

Spec file:
Expand All @@ -38,5 +40,6 @@ Spec file:
### Logs

```
// REPLACE ME: Paste the build ouput containing the error
// REPLACE ME: Paste the build output containing the error
// Keep the triple grave accent (a.k.a. backquote/backtick) to have the code formatted
```
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,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-no-venv/armeabi-v7a
script: make testapps/armeabi-v7a
- <<: *testapps
name: Rebuild updated recipes
script: travis_wait 30 make docker/run/make/rebuild_updated_recipes
Expand Down
12 changes: 6 additions & 6 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,19 @@
# Use 'docker run' without '--rm' flag for keeping the container and use
# 'docker commit <container hash> <new image>' to extend the original image

FROM ubuntu:18.04
FROM ubuntu:20.04

# configure locale
RUN apt update -qq > /dev/null && apt install -qq --yes --no-install-recommends \
RUN apt -y update -qq > /dev/null \
&& DEBIAN_FRONTEND=noninteractive 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 > /dev/null && apt -y install -qq --no-install-recommends \
RUN apt -y update -qq > /dev/null \
&& DEBIAN_FRONTEND=noninteractive apt install -qq --yes --no-install-recommends \
ca-certificates \
curl \
&& apt -y autoremove \
Expand All @@ -49,7 +51,7 @@ ENV WORK_DIR="${HOME_DIR}/app" \
# install system dependencies
RUN dpkg --add-architecture i386 \
&& ${RETRY} apt -y update -qq > /dev/null \
&& ${RETRY} apt -y install -qq --no-install-recommends \
&& ${RETRY} DEBIAN_FRONTEND=noninteractive apt install -qq --yes --no-install-recommends \
autoconf \
automake \
autopoint \
Expand All @@ -64,8 +66,6 @@ RUN dpkg --add-architecture i386 \
libidn11:i386 \
libltdl-dev \
libncurses5:i386 \
libpangox-1.0-0:i386 \
libpangoxft-1.0-0:i386 \
libssl-dev \
libstdc++6:i386 \
libtool \
Expand Down
12 changes: 2 additions & 10 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ all: virtualenv

$(VIRTUAL_ENV):
python3 -m venv $(VIRTUAL_ENV)
$(PIP) install Cython==0.28.6
$(PIP) install Cython==0.29.19
$(PIP) install -e .

virtualenv: $(VIRTUAL_ENV)
Expand All @@ -38,7 +38,7 @@ testapps-with-numpy/%: virtualenv
$(eval $@_APP_ARCH := $(shell basename $*))
. $(ACTIVATE) && cd testapps/on_device_unit_tests/ && \
python setup.py apk --sdk-dir $(ANDROID_SDK_HOME) --ndk-dir $(ANDROID_NDK_HOME) \
--requirements libffi,sdl2,pyjnius,kivy,python3,openssl,requests,sqlite3,setuptools,numpy \
--requirements libffi,sdl2,pyjnius,kivy,python3,openssl,requests,urllib3,chardet,idna,sqlite3,setuptools,numpy \
--arch=$($@_APP_ARCH)

testapps/%: virtualenv
Expand All @@ -47,14 +47,6 @@ testapps/%: virtualenv
python setup.py apk --sdk-dir $(ANDROID_SDK_HOME) --ndk-dir $(ANDROID_NDK_HOME) \
--arch=$($@_APP_ARCH)

testapps-no-venv/%:
pip3 install Cython==0.28.6
pip3 install -e .
$(eval $@_APP_ARCH := $(shell basename $*))
cd testapps/on_device_unit_tests/ && \
python3 setup.py apk --sdk-dir $(ANDROID_SDK_HOME) --ndk-dir $(ANDROID_NDK_HOME) \
--arch=$($@_APP_ARCH)

clean:
find . -type d -name "__pycache__" -exec rm -r {} +
find . -type d -name "*.egg-info" -exec rm -r {} +
Expand Down
1 change: 0 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ dependencies you want, and bundle it in an APK along with your own code.

Features include:

- Support for building with both Python 2 and Python 3.
- Different app backends including Kivy, PySDL2, and a WebView with
Python webserver.
- Automatic support for most pure Python modules, and built in support
Expand Down
2 changes: 1 addition & 1 deletion ci/makefiles/osx.mk
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ install_java:
/usr/libexec/java_home -V

upgrade_cython:
pip3 install --upgrade Cython==0.28.6
pip3 install --upgrade Cython==0.29.19

install_android_ndk_sdk:
mkdir -p $(ANDROID_HOME)
Expand Down
25 changes: 14 additions & 11 deletions doc/source/contribute.rst
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,8 @@ At this point, wait for reviewer approval and conclude any discussion that arise
- Merge the release branch to the ``master`` branch.
- Also merge the release branch to the ``develop`` branch.
- Tag the release commit in ``master``, with tag ``vYYYY.MM.DD``. Include a short summary of the changes.
- Create the release distributions: ``python3 setup.py sdist bdist_wheel``
- Upload the release to pypi: ``python3 -m twine upload``.
- Release distributions and PyPI upload should be `handled by the CI
<https://github.com/kivy/python-for-android/blob/v2020.04.29/.travis.yml#L60-L70>`_.
- Add to the Github release page (see e.g. `this example <https://github.com/kivy/python-for-android/releases/tag/v2019.06.06>`__):
- The python-for-android README summary
- A short list of major changes in this release, if any
Expand All @@ -67,15 +67,18 @@ At this point, wait for reviewer approval and conclude any discussion that arise

Release checklist
~~~~~~~~~~~~~~~~~

- [ ] Check that the [build is passing](https://travis-ci.org/kivy/python-for-android)
- [ ] Run the tests locally via `tox`: this performs some long-running tests that are skipped on Travis.
- [ ] Build and run the [on_device_unit_tests](https://github.com/kivy/python-for-android/tree/master/testapps/on_device_unit_tests) app using buildozer. Check that they all pass.
- [ ] Build and run the following [testapps](https://github.com/kivy/python-for-android/tree/master/testapps) for arch `armeabi-v7a` and `arm64-v8a`:
- `python3 setup_testapp_python3_sqlite_openssl.py apk`
- [ ] `armeabi-v7a`
- [ ] `arm64-v8a`
- [ ] Check that the version number is correct
::

- [ ] Check that the builds are passing
- [ ] [Travis build](https://travis-ci.org/kivy/python-for-android)
- [ ] [GitHub Action](https://github.com/kivy/python-for-android/actions)
- [ ] Run the tests locally via `tox`: this performs some long-running tests that are skipped on Travis.
- [ ] Build and run the [on_device_unit_tests](https://github.com/kivy/python-for-android/tree/master/testapps/on_device_unit_tests) app using buildozer. Check that they all pass.
- [ ] Build (or download from github actions) and run the following [testapps](https://github.com/kivy/python-for-android/tree/master/testapps/on_device_unit_tests) for arch `armeabi-v7a` and `arm64-v8a`:
- [ ] on_device_unit_tests
- [ ] `armeabi-v7a` (`cd testapps/on_device_unit_tests && PYTHONPATH=.:../../ python3 setup.py apk --ndk-dir=<your-ndk-dir> --sdk-dir=<your-sdk-dir> --arch=armeabi-v7a --debug`)
- [ ] `arm64-v8a` (`cd testapps/on_device_unit_tests && PYTHONPATH=.:../../ python3 setup.py apk --ndk-dir=<your-ndk-dir> --sdk-dir=<your-sdk-dir> --arch=arm64-v8a --debug`)
- [ ] Check that the version number is correct



Expand Down
14 changes: 11 additions & 3 deletions doc/source/quickstart.rst
Original file line number Diff line number Diff line change
Expand Up @@ -62,14 +62,16 @@ Installing Dependencies
p4a has several dependencies that must be installed:

- ant
- autoconf (for ffpyplayer_codecs recipe)
- autoconf (for libffi and other recipes)
- automake
- ccache (optional)
- cmake (required for some native code recipes like jpeg's recipe)
- cython (can be installed via pip)
- gcc
- git
- libncurses (including 32 bit)
- libtool (for ffpyplayer_codecs recipe)
- libtool (for libffi and recipes)
- libssl-dev (for TLS/SSL support on hostpython3 and recipe)
- openjdk-8
- patch
- python3
Expand All @@ -83,14 +85,20 @@ install most of these with::

sudo dpkg --add-architecture i386
sudo apt-get update
sudo apt-get install -y build-essential ccache git zlib1g-dev python3 python3-dev libncurses5:i386 libstdc++6:i386 zlib1g:i386 openjdk-8-jdk unzip ant ccache autoconf libtool
sudo apt-get install -y build-essential ccache git zlib1g-dev python3 python3-dev libncurses5:i386 libstdc++6:i386 zlib1g:i386 openjdk-8-jdk unzip ant ccache autoconf libtool libssl-dev

On Arch Linux you should be able to run the following to
install most of the dependencies (note: this list may not be
complete)::

sudo pacman -S core/autoconf core/automake core/gcc core/make core/patch core/pkgconf extra/cmake extra/jdk8-openjdk extra/python-pip extra/unzip extra/zip

On macOS::

brew install autoconf automake libtool openssl pkg-config
brew tap homebrew/cask-versions
brew cask install homebrew/cask-versions/adoptopenjdk8

Installing Android SDK
~~~~~~~~~~~~~~~~~~~~~~

Expand Down
34 changes: 28 additions & 6 deletions doc/source/troubleshooting.rst
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,17 @@ On Ubuntu fix it my making sure only the :code:`openjdk-8-jdk` package is instal
In the similar fashion for macOS you need to install the :code:`java8` package::

brew cask install java8
export JAVA_HOME=/Library/Java/JavaVirtualMachines/adoptopenjdk-8.jdk/Contents/Home


Error: Cask 'java8' is unavailable: No Cask with this name exists
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

In order to install Java 8 on macOS you may need extra steps::

brew tap homebrew/cask-versions
brew cask install homebrew/cask-versions/adoptopenjdk8
export JAVA_HOME=/Library/Java/JavaVirtualMachines/adoptopenjdk-8.jdk/Contents/Home


JNI DETECTED ERROR IN APPLICATION: static jfieldID 0x0000000 not valid for class java.lang.Class<org.renpy.android.PythonActivity>
Expand All @@ -173,12 +184,6 @@ This error appears in the logcat log if you try to access
fix it, change your code to reference
``org.kivy.android.PythonActivity`` instead.

websocket-client: if you see errors relating to 'SSL not available'
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Ensure you have the package backports.ssl-match-hostname in the buildozer requirements, since Kivy targets python 2.7.x

You may also need sslopt={"cert_reqs": ssl.CERT_NONE} as a parameter to ws.run_forever() if you get an error relating to host verification

Requested API target 19 is not available, install it with the SDK android tool
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Expand All @@ -197,3 +202,20 @@ ModuleNotFoundError: No module named '_ctypes'
You do not have the libffi headers available to python-for-android, so you need to install them. On Ubuntu and derivatives these come from the `libffi-dev` package.

After installing the headers, clean the build (`p4a clean builds`, or with buildozer delete the `.buildozer` directory within your app directory) and run python-for-android again.

SSLError("Can't connect to HTTPS URL because the SSL module is not available.")
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Your `hostpython3` was compiled without SSL support. You need to install the SSL development files before rebuilding the `hostpython3` recipe.
Remember to always clean the build before rebuilding (`p4a clean builds`, or with buildozer `buildozer android clean`).

On Ubuntu and derivatives::

apt install libssl-dev
p4a clean builds # or with: buildozer `buildozer android clean

On macOS::

brew install openssl
sudo ln -sfn /usr/local/opt/openssl /usr/local/ssl
p4a clean builds # or with: buildozer `buildozer android clean
2 changes: 1 addition & 1 deletion pythonforandroid/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = '2020.04.29'
__version__ = '2020.06.02'
4 changes: 2 additions & 2 deletions pythonforandroid/archs.py
Original file line number Diff line number Diff line change
Expand Up @@ -145,9 +145,9 @@ def get_env(self, with_flags_in_cc=True):
+ " ".join(
[
"-L'"
+ l.replace("'", "'\"'\"'")
+ link_path.replace("'", "'\"'\"'")
+ "'" # no shlex.quote in py2
for l in self.extra_global_link_paths
for link_path in self.extra_global_link_paths
]
)
+ ' ' + ' '.join(self.common_ldflags).format(
Expand Down
27 changes: 23 additions & 4 deletions pythonforandroid/bootstrap.py
Original file line number Diff line number Diff line change
Expand Up @@ -132,9 +132,6 @@ def get_build_dir(self):
def get_dist_dir(self, name):
return join(self.ctx.dist_dir, name)

def get_common_dir(self):
return os.path.abspath(join(self.bootstrap_dir, "..", 'common'))

@property
def name(self):
modname = self.__class__.__module__
Expand All @@ -152,6 +149,23 @@ def get_bootstrap_dirs(self):
]
return bootstrap_dirs

def _copy_in_final_files(self):
if self.name == "sdl2":
# Get the paths for copying SDL2's java source code:
sdl2_recipe = Recipe.get_recipe("sdl2", self.ctx)
sdl2_build_dir = sdl2_recipe.get_jni_dir()
src_dir = join(sdl2_build_dir, "SDL", "android-project",
"app", "src", "main", "java",
"org", "libsdl", "app")
target_dir = join(self.dist_dir, 'src', 'main', 'java', 'org',
'libsdl', 'app')

# Do actual copying:
info('Copying in SDL2 .java files from: ' + str(src_dir))
if not os.path.exists(target_dir):
os.makedirs(target_dir)
copy_files(src_dir, target_dir, override=True)

def prepare_build_dir(self):
"""Ensure that a build dir exists for the recipe. This same single
dir will be used for building all different archs."""
Expand All @@ -168,7 +182,12 @@ def prepare_build_dir(self):
def prepare_dist_dir(self):
ensure_dir(self.dist_dir)

def run_distribute(self):
def assemble_distribution(self):
''' Copies all the files into the distribution (this function is
overridden by the specific bootstrap classes to do this)
and add in the distribution info.
'''
self._copy_in_final_files()
self.distribution.save_info(self.dist_dir)

@classmethod
Expand Down
Loading