diff --git a/.github/workflows/no-response.yml b/.github/workflows/no-response.yml new file mode 100644 index 0000000000..343d344560 --- /dev/null +++ b/.github/workflows/no-response.yml @@ -0,0 +1,32 @@ +name: No Response + +# Both `issue_comment` and `scheduled` event types are required for this Action +# to work properly. +on: + issue_comment: + types: [created] + schedule: + # Schedule for an arbitrary time (5am) once every day + - cron: '* 5 * * *' + +jobs: + noResponse: + # Don't run if in a fork + if: github.repository_owner == 'kivy' + runs-on: ubuntu-latest + steps: + - uses: lee-dohm/no-response@9bb0a4b5e6a45046f00353d5de7d90fb8bd773bb + # This commit hash targets release v0.5.0 of lee-dohm/no-response. + # Targeting a commit hash instead of a tag has been done for security reasons. + # Please be aware that the commit hash specifically targets the "Automatic compilation" + # done by `github-actions[bot]` as the `no-response` Action needs to be compiled. + with: + token: ${{ github.token }} + daysUntilClose: 42 + responseRequiredLabel: 'awaiting-reply' + closeComment: > + This issue has been automatically closed because there has been no response + to our request for more information from the original author. With only the + information that is currently in the issue, we don't have the means + to take action. Please reach out if you have or find the answers we need so + that we can investigate further. diff --git a/.github/workflows/support.yml b/.github/workflows/support.yml index 2907000010..a0693e7632 100644 --- a/.github/workflows/support.yml +++ b/.github/workflows/support.yml @@ -1,3 +1,8 @@ +# When a user creates an issue that is actually a support request, it should +# be closed with a friendly comment. +# +# This triggers on an issue being labelled with the `support` tag. + name: 'Support Requests' on: @@ -11,22 +16,30 @@ jobs: action: runs-on: ubuntu-latest steps: - - uses: dessant/support-requests@v2 + - uses: dessant/support-requests@v4 with: github-token: ${{ github.token }} support-label: 'support' issue-comment: > - πŸ‘‹ We use the issue tracker exclusively for bug reports and feature requests. - However, this issue appears to be a support request. Please use our - [support channels](https://github.com/kivy/python-for-android/blob/master/README.md#support) - to get help with the project. - - - If you're having trouble installing or using python-for-android, - maybe you could be interested in our [quickstart](https://python-for-android.readthedocs.io/en/latest/quickstart) guide. + πŸ‘‹ @{issue-author}, + Sorry to hear you are having difficulties with Kivy's python-for-android; Kivy unites a number of different technologies, so building apps can be temperamental. + + We try to use GitHub issues only to track work for developers to do to fix bugs and add new features to python-for-android. + However, this issue appears to be a support request. Please use our + [support channels](https://github.com/kivy/python-for-android/blob/master/CONTACT.md) + to get help with the project. + + If you're having trouble installing python-for-android, + please see our [quickstart](https://python-for-android.readthedocs.io/en/latest/quickstart) guide. + + If you're having trouble using python-for-android, + please see our [troubleshooting guide](https://python-for-android.readthedocs.io/en/latest/troubleshooting) + and [FAQ](https://github.com/kivy/python-for-android/blob/master/FAQ.md). + Let us know if this comment was made in error, and we'll be happy to reopen the issue. + close-issue: true - lock-issue: false \ No newline at end of file + lock-issue: false diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 0000000000..29d18faa24 --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,8 @@ +In the interest of fostering an open and welcoming community, we as +contributors and maintainers need to ensure participation in our project and +our sister projects is a harassment-free and positive experience for everyone. +It is vital that all interaction is conducted in a manner conveying respect, +open-mindedness and gratitude. + +Please consult the [latest Kivy Code of Conduct](https://github.com/kivy/kivy/blob/master/CODE_OF_CONDUCT.md). + diff --git a/CONTACT.md b/CONTACT.md new file mode 100644 index 0000000000..c778a77a17 --- /dev/null +++ b/CONTACT.md @@ -0,0 +1,6 @@ +# Contacting the Kivy Team + +If you are looking to contact the Kivy Team (who are responsible for managing +the python-for-android project), including looking for support, please see our +latest [Contact Us](https://github.com/kivy/kivy/blob/master/CONTACT.md) +document. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000000..be864e06f0 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,250 @@ +# Contribution Guidelines + +python-for-android is part of the [Kivy](https://kivy.org) ecosystem - a large group of +products used by many thousands of developers for free, but it +is built entirely by the contributions of volunteers. We welcome (and rely on) +users who want to give back to the community by contributing to the project. + +Contributions can come in many forms. See the latest +[Contribution Guidelines](https://github.com/kivy/kivy/blob/master/CONTRIBUTING.md) +for how you can help us. + +.. warning:: + The python-for-android process differs in small but important ways from the + Kivy framework's process. See below. + +## Development model + +Unlike the Kivy framework, python-for-android is developed using the following +model: + +- The `master` branch always represents the latest stable release. +- The `develop` branch is the most up to date with new contributions. +- Releases happen periodically, and consist of merging the current `develop` + branch into `master`. + +This means pull requests for python-for-android code and documentation +submissions should be made to the `develop` branch, not the `master` branch. + +For reference, this is based on a +[Git flow](https://nvie.com/posts/a-successful-git-branching-model/) model, +although we don't follow this religiously. + +## Versioning + +python-for-android releases currently use +[calendar versioning](https://calver.org/). Release numbers are of the form +YYYY.MM.DD. + +We use calendar versioning because in practice, changes in +python-for-android are often driven by updates or adjustments in the +Android build tools. It's usually best for users to be working from +the latest release. We try to maintain backwards compatibility even +while internals are changing. + +## History + +In 2015, these tools were rewritten to provide a new, easier-to-use and +easier-to-extend interface. If you'd like to browse the old toolchain, +its status is +[recorded for posterity](https://github.com/kivy/python-for-android/tree/old_toolchain). + +In the last quarter of 2018, the Python recipes were changed. The +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. 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). + +On March 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. + +On August 2021, we added support for Android App Bundle (aab). As a +collateral benefit, we now support multi-arch apk. + +## Creating a new release + +(These instructions are for core developers, not casual contributors.) + +New releases follow these steps: + +- Create a new branch `release-YYYY.MM.DD` based on the `develop` branch. + - `git checkout -b release-YYYY.MM.DD develop` +- Create a Github pull request to merge `release-YYYY.MM.DD` into `master`. +- Complete all steps in the [release checklist](#Release_checklist), + and document this in the pull request (copy the checklist into the PR text) + +At this point, wait for reviewer approval and conclude any discussion that +arises. To complete the release: + +- 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. +- 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 + - A changelog summarising merge commits since the last release + - The release sdist and wheel(s) + +## Release checklist + + - [ ] Check that the builds are passing + - [ ] [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 github-actions. + - [ ] 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= --sdk-dir= --arch=armeabi-v7a --debug`) + - [ ] `arm64-v8a` (`cd testapps/on_device_unit_tests && PYTHONPATH=.:../../ python3 setup.py apk --ndk-dir= --sdk-dir= --arch=arm64-v8a --debug`) + - [ ] Check that the version number is correct + +## How python-for-android uses `pip` + +*Last update: July 2019* + +This section is meant to provide a quick summary how +python-for-android uses pip and Python packages in +its build process. +**It is written for a Python +packager's point of view, not for regular end users or +contributors,** to assist with making pip developers and +other packaging experts aware of p4a's packaging needs. + +Please note this section just attempts to neutrally list the +current mechanisms, so some of this isn't necessarily meant +to stay but just how things work inside p4a in +this very moment. + + +### Basic concepts + +*(This part repeats other parts of the docs, for the sake of +making this a more independent read)* + +p4a builds & packages a Python application for use on Android. +It does this by providing a Java wrapper, and for graphical applications +an SDL2-based wrapper which can be used with the Kivy framework if +desired (or alternatively just plain PySDL2). Any such the Python application +will likely have further library dependencies to do its work. + +p4a supports two types of package dependencies for a project: + +**Recipe:** Install a script in custom p4a format. Can either install +C/C++ or other software that cannot be pulled in via pip, or software +that can be installed via pip but break on Android by default. +These are maintained primarily inside the p4a source tree by p4a +contributors and interested folks. + +**Python package:** any random pip python package can be directly +installed if it doesn't need adjustments to work for Android. + +p4a will map any dependency to an internal recipe if present, and +otherwise use pip to obtain it regularly from whatever external source. + + +### Install process regarding packages + +The install/build process of a p4a project, as triggered by the +`p4a apk` command, roughly works as follows in regards to Python +packages: + +1. The user has specified a project folder to install. This is either + just a folder with Python scripts and a `main.py`, or it may + also have a `pyproject.toml` for a more standardized install. + +2. Dependencies are collected: they can be either specified via + ``--requirements`` as a list of names or pip-style URLs, or p4a + can optionally scan them from a project folder via the + pep517 library (if there is a `pyproject.toml` or `setup.py`). + +3. The collected dependencies are mapped to p4a's recipes if any are + available for them, otherwise they're kept around as external + regular package references. + +4. All the dependencies mapped to recipes are built via p4a's internal + mechanisms to build these recipes. (This may or may not indirectly + use pip, depending on whether the recipe wraps a python package + or not and uses pip to install or not.) + +5. **If the user has specified to install the project in standardized + ways,** then the `setup.py`/whatever build system + of the project will be run. This happens with cross compilation set up + (`CC`/`CFLAGS`/... set to use the + proper toolchain) and a custom site-packages location. + The actual comand is a simple `pip install .` in the project folder + with some extra options: e.g. all dependencies that were already + installed by recipes will be pinned with a `-c` constraints file + to make sure pip won't install them, and build isolation will be + disabled via ``--no-build-isolation`` so pip doesn't reinstall + recipe-packages on its own. + + **If the user has not specified to use standardized build approaches**, + p4a will simply install all the remaining dependencies that weren't + mapped to recipes directly and just plain copy in the user project + without installing. Any `setup.py` or `pyproject.toml` of the user + project will then be ignored in this step. + +6. Google's gradle is invoked to package it all up into an `.apk`. + + +### Overall process / package relevant notes for p4a + +Here are some common things worth knowing about python-for-android's +dealing with python packages: + +- Packages will work fine without a recipe if: + + * they would also build on Linux ARM, + * don't use any API not available in the NDK if they use native code, and + * don't use any weird compiler flags the toolchain doesn't like if they use native code. + * works with cross compilation. + +- There is currently no easy way for a package to know it is being + cross-compiled (at least that we know of) other than examining the + `CC` compiler that was set, or that it is being cross-compiled for + Android specifically. If that breaks a package, it currently needs + to be worked around with a recipe. + +- If a package does **not** work, p4a developers will often create a + recipe instead of getting upstream to fix it because p4a simply + is too niche. + +- Most packages without native code will just work out of the box. + Many with native code tend not to, especially if complex, e.g. numpy. + +- Anything mapped to a p4a recipe cannot be just reinstalled by pip, + specifically also not inside build isolation as a dependency. + (It *may* work if the patches of the recipe are just relevant + to fix runtime issues.) + Therefore as of now, the best way to deal with this limitation seems + to be to keep build isolation always off. + + +### Ideas for the future regarding packaging + +- We in overall prefer to use the recipe mechanism less if we can. + Overall, the recipes are just a collection of workarounds. + It may look quite hacky from the outside, since p4a + version pins recipe-wrapped packages usually to make the patches reliably + apply. This creates work for the recipes to be kept up-to-date, and + obviously this approach doesn't scale too well. However, it has ended + up as a quite practical interim solution until better ways are found. + +- Obviously, it would be nice if packages could know they are being + cross-compiled, and for Android specifically. We aren't currently aware + of any good mechanism for that. + +- If pip could actually run the recipes (instead of p4a wrapping pip and + doing so) then this might even allow build isolation to work - but + this might be too complex to get working. It might be more practical + to just gradually reduce the reliance on recipes instead and make + more packages work out of the box. This has been done e.g. with + improvements to the cross-compile environment being set up automatically, + and we're open for any ideas on how to improve this. diff --git a/FAQ.md b/FAQ.md index 9e37084375..7450a6c44d 100644 --- a/FAQ.md +++ b/FAQ.md @@ -2,10 +2,8 @@ ## Introduction -[python-for-android](https://python-for-android.readthedocs.io/) is an open -source build tool to let you package Python code into standalone Android artifacts (APKs, AABs, AARs). -These can be passed around, installed, or uploaded to marketplaces such as the -Play Store just like any other Android app. +python-for-android (p4a) is a development tool that packages Python apps into +binaries that can run on Android devices. ### Sibling Projects: @@ -22,7 +20,7 @@ number of target platforms, using a specification file to define the build. ### Is it possible to have a kiosk app on Android? Thomas Hansen wrote a detailed answer -on [the kivy-users mailing list](https://groups.google.com/d/msg/kivy-users/QKoCekAR1c0/yV-85Y_iAwoJ) +on [the (old) kivy-users mailing list](https://groups.google.com/d/msg/kivy-users/QKoCekAR1c0/yV-85Y_iAwoJ) Basically, you need to root the device, remove the SystemUI package, add some lines to the xml configuration, and you're done. @@ -71,3 +69,46 @@ On macOS: brew install openssl p4a clean builds # or with: buildozer `buildozer android clean + + +#### AttributeError: 'AnsiCodes' object has no attribute 'LIGHTBLUE_EX' + +This occurs if your version of `colorama` is too low, install version +0.3.3 or higher. + +If you install python-for-android with `pip` or via `setup.py`, this +dependency should be taken care of automatically. + +#### 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=python3,kivy`. This also applies when using +buildozer, in which case add python3 to your buildozer.spec requirements. + +#### linkname too long + +This can happen when you try to include a very long filename, which +doesn't normally happen but can occur accidentally if the p4a +directory contains a .buildozer directory that is not excluded from +the build (e.g. if buildozer was previously used). Removing this +directory should fix the problem, and is desirable anyway since you +don't want it in the APK. + +#### Requested API target 19 is not available, install it with the SDK android tool + +This means that your SDK is missing the required platform tools. You +need to install the ``platforms;android-19`` package in your SDK, +using the ``android`` or ``sdkmanager`` tools (depending on SDK +version). + +If using buildozer this should be done automatically, but as a +workaround you can run these from +``~/.buildozer/android/platform/android-sdk-20/tools/android``. + +#### 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. + diff --git a/LICENSE b/LICENSE index d5d6b13c85..4e3506010a 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,6 @@ -Copyright (c) 2010-2017 Kivy Team and other contributors +MIT License + +Copyright (c) 2010-2023 Kivy Team and other contributors Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/README.md b/README.md index 764ea7b7a7..c7cbb96c9a 100644 --- a/README.md +++ b/README.md @@ -1,144 +1,124 @@ -python-for-android -================== +# python-for-android + +python-for-android (p4a) is a development tool that packages Python apps into +binaries that can run on Android devices. + +It can generate: + +* [Android Package](https://en.wikipedia.org/wiki/Apk_(file_format)) (APK) + files, ready to install locally on a device, especially for testing. This format + is used by many [app stores](https://en.wikipedia.org/wiki/List_of_Android_app_stores) + but not [Google Play Store](https://play.google.com/store/). +* [Android App Bundle](https://developer.android.com/guide/app-bundle/faq) + (AAB) files which can be shared on [Google Play Store](https://play.google.com/store/). +* [Android Archive](https://developer.android.com/studio/projects/android-library) + (AAR) files which can be used as a re-usable bundle of resources for other + projects. + +It supports multiple CPU architectures. + +It supports apps developed with [Kivy framework](http://kivy.org), but was +built to be flexible about the backend libraries (through "bootstraps"), and +also supports [PySDL2](https://pypi.org/project/PySDL2/), and a +[WebView](https://developer.android.com/reference/android/webkit/WebView) with +a Python web server. + +It automatically supports dependencies on most pure Python packages. For other +packages, including those that depend on C code, a special "recipe" must be +written to support cross-compiling. python-for-android comes with recipes for +many of the mosty popular libraries (e.g. numpy and sqlalchemy) built in. + +python-for-android works by cross-compiling the Python interpreter and its +dependencies for Android devices, and bundling it with the app's python code +and dependencies. The Python code is then interpreted on the Android device. + +It is recommended that python-for-android be used via +[Buildozer](https://buildozer.readthedocs.io/), which ensures the correct +dependencies are pre-installed, and centralizes the configuration. However, +python-for-android is not limited to being used with Buildozer. -[![Unit tests & build apps](https://github.com/kivy/python-for-android/workflows/Unit%20tests%20&%20build%20apps/badge.svg?branch=develop)](https://github.com/kivy/python-for-android/actions?query=workflow%3A%22Unit+tests+%26+build+apps%22) -[![Coverage Status](https://coveralls.io/repos/github/kivy/python-for-android/badge.svg?branch=develop&kill_cache=1)](https://coveralls.io/github/kivy/python-for-android?branch=develop) [![Backers on Open Collective](https://opencollective.com/kivy/backers/badge.svg)](#backers) [![Sponsors on Open Collective](https://opencollective.com/kivy/sponsors/badge.svg)](#sponsors) +[![GitHub contributors](https://img.shields.io/github/contributors-anon/kivy/python-for-android)](https://github.com/kivy/python-for-android/graphs/contributors) +[![Contributor Covenant](https://img.shields.io/badge/Contributor%20Covenant-2.1-4baaaa.svg)](CODE_OF_CONDUCT.md) -python-for-android is a packaging tool for Python apps on Android. You can -create your own Python distribution including the modules and -dependencies you want, and bundle it in an APK or AAB along with your own code. - -Features include: - -- Different app backends including Kivy, PySDL2, and a WebView with - Python webserver. -- Automatic support for most pure Python modules, and built in support - for many others, including popular dependencies such as numpy and - sqlalchemy. -- Multiple architecture targets, for APKs optimised on any given - device. -- AAB: Android App Bundle support. +![PyPI - Version](https://img.shields.io/pypi/v/python-for-android) +![PyPI - Python Version](https://img.shields.io/pypi/pyversions/python-for-android) -For documentation and support, see: - -- Website: http://python-for-android.readthedocs.io -- Mailing list: https://groups.google.com/forum/#!forum/kivy-users or - https://groups.google.com/forum/#!forum/python-android. +[![Unit tests & build apps](https://github.com/kivy/python-for-android/workflows/Unit%20tests%20&%20build%20apps/badge.svg?branch=develop)](https://github.com/kivy/python-for-android/actions?query=workflow%3A%22Unit+tests+%26+build+apps%22) +[![Coverage Status](https://coveralls.io/repos/github/kivy/python-for-android/badge.svg?branch=develop&kill_cache=1)](https://coveralls.io/github/kivy/python-for-android?branch=develop) ## Documentation -Follow the [quickstart -instructions]() -to install and begin creating APKs and AABs. - -**Quick instructions**: install python-for-android with: - - pip install python-for-android - -(for the develop branch: `pip install git+https://github.com/kivy/python-for-android.git`) - -Test that the install works with: - - p4a --version - -To build any actual apps, **set up the Android SDK and NDK** -as described in the [quickstart]( -). -**Use the SDK/NDK API level & NDK version as in the quickstart,** -other API levels may not work. - -With everything installed, build an APK with SDL2 with e.g.: - - p4a apk --private PATH_TO_YOUR_APP_CODE --package=org.example.myapp --name "My application" --version 0.1 --bootstrap=sdl2 --requirements=python3,kivy - -**If you need to deploy your app on Google Play, Android App Bundle (aab) is required since 1 August 2021:** +More information is available in the +[online documentation](https://python-for-android.readthedocs.io) including a +[quickstart guide](https://python-for-android.readthedocs.io/en/latest/quickstart/). -**For full instructions and parameter options,** see [the -documentation](https://python-for-android.readthedocs.io/en/latest/quickstart/#usage). +python-for-android is managed by the [Kivy team](https://kivy.org). ## Support -If you need assistance, you can ask for help on our mailing list: +Are you having trouble using python-for-android or any of its related projects +in the Kivy ecosystem? +Is there an error you don’t understand? Are you trying to figure out how to use +it? We have volunteers who can help! -- User Group: https://groups.google.com/group/kivy-users -- Email: kivy-users@googlegroups.com +The best channels to contact us for support are listed in the latest +[Contact Us](https://github.com/kivy/pyton-for-android/blob/master/CONTACT.md) +document. -We also have [#support Discord channel](https://chat.kivy.org/). +## Code of Conduct -## Contributing +In the interest of fostering an open and welcoming community, we as +contributors and maintainers need to ensure participation in our project and +our sister projects is a harassment-free and positive experience for everyone. +It is vital that all interaction is conducted in a manner conveying respect, +open-mindedness and gratitude. -We love pull requests and discussing novel ideas. Check out the Kivy -project [contribution guide](https://kivy.org/doc/stable/contribute.html) and -feel free to improve python-for-android. - -See [our -documentation](https://python-for-android.readthedocs.io/en/latest/contribute/) -for more information about the python-for-android development and -release model, but don't worry about the details. You just need to -make a pull request, we'll take care of the rest. - -The following mailing list and IRC channel are used exclusively for -discussions about developing the Kivy framework and its sister projects: - -- Dev Group: https://groups.google.com/group/kivy-dev -- Email: kivy-dev@googlegroups.com - -We also have [#dev Discord channel](https://chat.kivy.org/). - -## License - -python-for-android is released under the terms of the MIT License. -Please refer to the LICENSE file. - -## History - -In 2015 these tools were rewritten to provide a new, easier-to-use and -easier-to-extend interface. If you'd like to browse the old toolchain, its -status is recorded for posterity at -https://github.com/kivy/python-for-android/tree/old_toolchain. - -In the last quarter of 2018 the python recipes were changed. The -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. 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). - -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. - -On August of 2021, we added support for Android App Bundle (aab). As a collateral, -now We support multi-arch apk. +Please consult the [latest Code of Conduct](https://github.com/kivy/python-for-android/blob/master/CODE_OF_CONDUCT.md). ## Contributors -This project exists thanks to all the people who contribute. [[Contribute](https://kivy.org/doc/stable/contribute.html)]. - +This project exists thanks to +[all the people who contribute](https://github.com/kivy/python-for-android/graphs/contributors). +[[Become a contributor](CONTRIBUTING.md)]. + ## Backers -Thank you to all our backers! πŸ™ [[Become a backer](https://opencollective.com/kivy#backer)] - - +Thank you to [all of our backers](https://opencollective.com/kivy)! +πŸ™ [[Become a backer](https://opencollective.com/kivy#backer)] + ## Sponsors -Support this project by becoming a sponsor. Your logo will show up here with a link to your website. [[Become a sponsor](https://opencollective.com/kivy#sponsor)] +Special thanks to +[all of our sponsors, past and present](https://opencollective.com/kivy). +Support this project by +[[becoming a sponsor](https://opencollective.com/kivy#sponsor)]. +Here are our top current sponsors. Please click through to see their websites, +and support them as they support us. + + + + + + + + + + + diff --git a/doc/source/conf.py b/doc/source/conf.py index a355505748..773083f980 100644 --- a/doc/source/conf.py +++ b/doc/source/conf.py @@ -58,7 +58,7 @@ author = 'Kivy Team and other contributors' -copyright = f'{_today.year}, {author}' +copyright = f'2015-{_today.year}, {author}' # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the @@ -290,7 +290,9 @@ def get_version(): # dir menu entry, description, category) texinfo_documents = [ (master_doc, 'python-for-android', u'python-for-android Documentation', - author, 'python-for-android', 'One line description of project.', + author, 'python-for-android', + 'A development tool that packages Python apps into binaries that can run on ' + 'Android devices', 'Miscellaneous'), ] diff --git a/doc/source/contact.rst b/doc/source/contact.rst new file mode 100644 index 0000000000..fedc04b47f --- /dev/null +++ b/doc/source/contact.rst @@ -0,0 +1,6 @@ +Contact Us +========== + +If you are looking to contact the Kivy Team (who are responsible for managing the +python-for-android project), including looking for support, please see our +`latest contact details `_. \ No newline at end of file diff --git a/doc/source/contribute.rst b/doc/source/contribute.rst index c66cd096ea..653c670081 100644 --- a/doc/source/contribute.rst +++ b/doc/source/contribute.rst @@ -1,231 +1,19 @@ -Development and Contributing -============================ +.. _contributing: -The development of python-for-android is managed by the Kivy team `via -Github `_. +.. _contribute: -Issues and pull requests are welcome via the integrated `issue tracker -`_. +Contribution Guidelines +======================= -Read on for more information about how we manage development and -releases, but don't worry about the details! Pull requests are welcome -and we'll deal with the rest. +Buildozer is part of the `Kivy `_ ecosystem - a large group of +products used by many thousands of developers for free, but it +is built entirely by the contributions of volunteers. We welcome (and rely on) +users who want to give back to the community by contributing to the project. -Development model ------------------ - -python-for-android is developed using the following model: - -- The ``master`` branch always represents the latest stable release. -- The ``develop`` branch is the most up to date with new contributions. -- Releases happen periodically, and consist of merging the current ``develop`` branch into ``master``. - -For reference, this is based on a `Git flow -`__ model, -although we don't follow this religiously. - -Versioning ----------- - -python-for-android releases currently use `calendar versioning -`__. Release numbers are of the form -YYYY.MM.DD. We aim to create a new release every four weeks, but more -frequent releases are also possible. - -We use calendar versioning because in practice, changes in -python-for-android are often driven by updates or adjustments in the -Android build tools. It's usually best for users to be working from -the latest release. We try to maintain backwards compatibility even -while internals are changing. - - -Creating a new release ----------------------- - -New releases follow these steps: - -- Create a new branch ``release-YYYY.MM.DD`` based on the ``develop`` branch. - - ``git checkout -b release-YYYY.MM.DD develop`` -- Create a Github pull request to merge ``release-YYYY.MM.DD`` into ``master``. -- Complete all steps in the `release checklist `_, - and document this in the pull request (copy the checklist into the PR text) - -At this point, wait for reviewer approval and conclude any discussion that arises. To complete the release: - -- 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. -- Release distributions and PyPI upload should be `handled by the CI - `_. -- Add to the Github release page (see e.g. `this example `__): - - The python-for-android README summary - - A short list of major changes in this release, if any - - A changelog summarising merge commits since the last release - - The release sdist and wheel(s) - -.. _release_checklist: - -Release checklist -~~~~~~~~~~~~~~~~~ -:: - - - [ ] Check that the builds are passing - - [ ] [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 github-actions. - - [ ] 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= --sdk-dir= --arch=armeabi-v7a --debug`) - - [ ] `arm64-v8a` (`cd testapps/on_device_unit_tests && PYTHONPATH=.:../../ python3 setup.py apk --ndk-dir= --sdk-dir= --arch=arm64-v8a --debug`) - - [ ] Check that the version number is correct - - - -How python-for-android uses `pip` ---------------------------------- - -*Last update: July 2019* - -This section is meant to provide a quick summary how -p4a (=python-for-android) uses pip and python packages in -its build process. -**It is written for a python -packagers point of view, not for regular end users or -contributors,** to assist with making pip developers and -other packaging experts aware of p4a's packaging needs. - -Please note this section just attempts to neutrally list the -current mechanisms, so some of this isn't necessarily meant -to stay but just how things work inside p4a in -this very moment. - - -Basic concepts -~~~~~~~~~~~~~~ - -*(This part repeats other parts of the docs, for the sake of -making this a more independent read)* - -p4a builds & packages a python application for use on Android. -It does this by providing a Java wrapper, and for graphical applications -an SDL2-based wrapper which can be used with the kivy UI toolkit if -desired (or alternatively just plain PySDL2). Any such python application -will of course have further library dependencies to do its work. - -p4a supports two types of package dependencies for a project: - -**Recipe:** install script in custom p4a format. Can either install -C/C++ or other things that cannot be pulled in via pip, or things -that can be installed via pip but break on android by default. -These are maintained primarily inside the p4a source tree by p4a -contributors and interested folks. - -**Python package:** any random pip python package can be directly -installed if it doesn't need adjustments to work for Android. - -p4a will map any dependency to an internal recipe if present, and -otherwise use pip to obtain it regularly from whatever external source. - - -Install process regarding packages -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -The install/build process of a p4a project, as triggered by the -`p4a apk` command, roughly works as follows in regards to python -packages: - -1. The user has specified a project folder to install. This is either - just a folder with python scripts and a `main.py`, or it may - also have a `pyproject.toml` for a more standardized install. - -2. Dependencies are collected: they can be either specified via - ``--requirements`` as a list of names or pip-style URLs, or p4a - can optionally scan them from a project folder via the - pep517 library (if there is a `pyproject.toml` or `setup.py`). - -3. The collected dependencies are mapped to p4a's recipes if any are - available for them, otherwise they're kept around as external - regular package references. - -4. All the dependencies mapped to recipes are built via p4a's internal - mechanisms to build these recipes. (This may or may not indirectly - use pip, depending on whether the recipe wraps a python package - or not and uses pip to install or not.) - -5. **If the user has specified to install the project in standardized - ways,** then the `setup.py`/whatever build system - of the project will be run. This happens with cross compilation set up - (`CC`/`CFLAGS`/... set to use the - proper toolchain) and a custom site-packages location. - The actual comand is a simple `pip install .` in the project folder - with some extra options: e.g. all dependencies that were already - installed by recipes will be pinned with a `-c` constraints file - to make sure pip won't install them, and build isolation will be - disabled via ``--no-build-isolation`` so pip doesn't reinstall - recipe-packages on its own. - - **If the user has not specified to use standardized build approaches**, - p4a will simply install all the remaining dependencies that weren't - mapped to recipes directly and just plain copy in the user project - without installing. Any `setup.py` or `pyproject.toml` of the user - project will then be ignored in this step. - -6. Google's gradle is invoked to package it all up into an `.apk`. - - -Overall process / package relevant notes for p4a -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Here are some common things worth knowing about python-for-android's -dealing with python packages: - -- Packages will work fine without a recipe if they would also build - on Linux ARM, don't use any API not available in the NDK if they - use native code, and don't use any weird compiler flags the toolchain - doesn't like if they use native code. The package also needs to - work with cross compilation. - -- There is currently no easy way for a package to know it is being - cross-compiled (at least that we know of) other than examining the - `CC` compiler that was set, or that it is being cross-compiled for - Android specifically. If that breaks a package it currently needs - to be worked around with a recipe. - -- If a package does **not** work, p4a developers will often create a - recipe instead of getting upstream to fix it because p4a simply - is too niche. - -- Most packages without native code will just work out of the box. - Many with native code tend not to, especially if complex, e.g. numpy. - -- Anything mapped to a p4a recipe cannot be just reinstalled by pip, - specifically also not inside build isolation as a dependency. - (It *may* work if the patches of the recipe are just relevant - to fix runtime issues.) - Therefore as of now, the best way to deal with this limitation seems - to be to keep build isolation always off. - - -Ideas for the future regarding packaging -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -- We in overall prefer to use the recipe mechanism less if we can. - In overall the recipes are just a collection of workarounds. - It may look quite hacky from the outside, since p4a - version pins recipe-wrapped packages usually to make the patches reliably - apply. This creates work for the recipes to be kept up-to-date, and - obviously this approach doesn't scale too well. However, it has ended - up as a quite practical interims solution until better ways are found. - -- Obviously, it would be nice if packages could know they are being - cross-compiled, and for Android specifically. We aren't currently aware - of a good mechanism for that. - -- If pip could actually run the recipes (instead of p4a wrapping pip and - doing so) then this might even allow build isolation to work - but - this might be too complex to get working. It might be more practical - to just gradually reduce the reliance on recipes instead and make - more packages work out of the box. This has been done e.g. with - improvements to the cross-compile environment being set up automatically, - and we're open for any ideas on how to improve this. +Contributions can come in many forms. See the latest +`Contribution Guidelines `_ +for general guidelines of how you can help us, and specific instructions for python-for-android +development. +.. warning:: + The python-for-android process differs in small but important ways from the Kivy framework's process. diff --git a/doc/source/faq.rst b/doc/source/faq.rst new file mode 100644 index 0000000000..6527cf3c29 --- /dev/null +++ b/doc/source/faq.rst @@ -0,0 +1,5 @@ +FAQ +=== + +python-for-android has an `online FAQ `_. It contains +the answers to questions that repeatedly come up. diff --git a/doc/source/index.rst b/doc/source/index.rst index 5faf83da49..929fa384c7 100644 --- a/doc/source/index.rst +++ b/doc/source/index.rst @@ -1,23 +1,48 @@ python-for-android ================== -python-for-android is an open source build tool to let you package -Python code into standalone android APKs. These can be passed around, -installed, or uploaded to marketplaces such as the Play Store just -like any other Android app. This tool was originally developed for the -`Kivy cross-platform graphical framework `_, -but now supports multiple bootstraps and can be easily extended to -package other types of Python apps for Android. - -python-for-android supports two major operations; first, it can -compile the Python interpreter, its dependencies, backend libraries -and python code for Android devices. This stage is fully customisable: -you can install as many or few components as you like. The result is -a standalone Android project which can be used to generate any number -of different APKs, even with different names, icons, Python code etc. -The second function of python-for-android is to provide a simple -interface to these distributions, to generate from such a project a -Python APK with build parameters and Python code to taste. +python-for-android (p4a) is a development tool that packages Python apps into +binaries that can run on Android devices. + +It can generate: + +* `Android Package `_ (APK) + files, ready to install locally on a device, especially for testing. This format + is used by many `app stores `_ + but not `Google Play Store `_. +* `Android App Bundle `_ + (AAB) files which can be shared on `Google Play Store `_. +* `Android Archive `_ + (AAR) files which can be used as a re-usable bundle of resources for other + projects. + +It supports multiple CPU architectures. + +It supports apps developed with `Kivy framework `_, but was +built to be flexible about the backend libraries (through "bootstraps"), and +also supports `PySDL2 `_, and a +`WebView `_ with +a Python web server. + +It automatically supports dependencies on most pure Python packages. For other +packages, including those that depend on C code, a special "recipe" must be +written to support cross-compiling. python-for-android comes with recipes for +many of the mosty popular libraries (e.g. numpy and sqlalchemy) built in. + +python-for-android works by cross-compiling the Python interpreter and its +dependencies for Android devices, and bundling it with the app's python code +and dependencies. The Python code is then interpreted on the Android device. + +It is recommended that python-for-android be used via +`Buildozer `_, which ensures the correct +dependencies are pre-installed, and centralizes the configuration. However, +python-for-android is not limited to being used with Buildozer. + +Buildozer is released and distributed under the terms of the MIT license. You +should have received a +copy of the MIT license alongside your distribution. Our +`latest license `_ +is also available. Contents @@ -36,8 +61,10 @@ Contents services troubleshooting docker - contribute testing_pull_requests + faq + contribute + contact Indices and tables diff --git a/doc/source/troubleshooting.rst b/doc/source/troubleshooting.rst index d9f309db9e..25f8cbc04b 100644 --- a/doc/source/troubleshooting.rst +++ b/doc/source/troubleshooting.rst @@ -15,20 +15,6 @@ include this full log, e.g. via a `pastebin `_ or `Github gist `_. -Getting help ------------- - -python-for-android is managed by the Kivy Organisation, and you can -get help with any problems using the same channels as Kivy itself: - -- by email to the `kivy-users Google group - `_ -- on `#support Discord channel `_ - -If you find a bug, you can also post an issue on the -`python-for-android Github page -`_. - Debugging on Android -------------------- @@ -114,73 +100,8 @@ For example, the Python installation for ``arm64-v8a`` is available in ``lib/arm $ ls modules site-packages stdlib.zip +FAQ +--- - -Common errors -------------- - -The following are common problems and resolutions that users have reported. - - -AttributeError: 'AnsiCodes' object has no attribute 'LIGHTBLUE_EX' -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -This occurs if your version of colorama is too low, install version -0.3.3 or higher. - -If you install python-for-android with pip or via setup.py, this -dependency should be taken care of automatically. - -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=python3,kivy`. This also applies when using -buildozer, in which case add python3 to your buildozer.spec requirements. - -linkname too long -~~~~~~~~~~~~~~~~~ - -This can happen when you try to include a very long filename, which -doesn't normally happen but can occur accidentally if the p4a -directory contains a .buildozer directory that is not excluded from -the build (e.g. if buildozer was previously used). Removing this -directory should fix the problem, and is desirable anyway since you -don't want it in the APK. - -Requested API target 19 is not available, install it with the SDK android tool -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -This means that your SDK is missing the required platform tools. You -need to install the ``platforms;android-19`` package in your SDK, -using the ``android`` or ``sdkmanager`` tools (depending on SDK -version). - -If using buildozer this should be done automatically, but as a -workaround you can run these from -``~/.buildozer/android/platform/android-sdk-20/tools/android``. - -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 +Check out the `online FAQ `_ for common +errors. \ No newline at end of file diff --git a/setup.py b/setup.py index 6351cdcf8a..badce08e82 100644 --- a/setup.py +++ b/setup.py @@ -34,7 +34,8 @@ def recursively_include(results, directory, patterns): for root, subfolders, files in walk(directory): for fn in files: - if not any(glob.fnmatch.fnmatch(fn, pattern) for pattern in patterns): + if not any( + glob.fnmatch.fnmatch(fn, pattern) for pattern in patterns): continue filename = join(root, fn) directory = 'pythonforandroid' @@ -47,9 +48,12 @@ def recursively_include(results, directory, patterns): ['*.patch', 'Setup*', '*.pyx', '*.py', '*.c', '*.h', '*.mk', '*.jam', '*.diff', ]) recursively_include(package_data, 'pythonforandroid/bootstraps', - ['*.properties', '*.xml', '*.java', '*.tmpl', '*.txt', '*.png', - '*.mk', '*.c', '*.h', '*.py', '*.sh', '*.jpg', '*.aidl', - '*.gradle', '.gitkeep', 'gradlew*', '*.jar', "*.patch", ]) + [ + '*.properties', '*.xml', '*.java', '*.tmpl', '*.txt', + '*.png', '*.mk', '*.c', '*.h', '*.py', '*.sh', '*.jpg', + '*.aidl', '*.gradle', '.gitkeep', 'gradlew*', '*.jar', + '*.patch', + ]) recursively_include(package_data, 'pythonforandroid/bootstraps', ['sdl-config', ]) recursively_include(package_data, 'pythonforandroid/bootstraps/webview', @@ -59,8 +63,7 @@ def recursively_include(results, directory, patterns): with open(join(dirname(__file__), 'README.md'), encoding="utf-8", - errors="replace", - ) as fileh: + errors="replace", ) as fileh: long_description = fileh.read() init_filen = join(dirname(__file__), 'pythonforandroid', '__init__.py') @@ -68,8 +71,7 @@ def recursively_include(results, directory, patterns): try: with open(init_filen, encoding="utf-8", - errors="replace" - ) as fileh: + errors="replace") as fileh: lines = fileh.readlines() except IOError: pass @@ -82,15 +84,19 @@ def recursively_include(results, directory, patterns): version = matches[0].strip("'").strip('"') break if version is None: - raise Exception('Error: version could not be loaded from {}'.format(init_filen)) + raise Exception( + 'Error: version could not be loaded from {}'.format(init_filen)) setup(name='python-for-android', version=version, - description='Android APK packager for Python scripts and apps', + description=( + 'A development tool that packages Python apps into ' + 'binaries that can run on Android devices.' + ), long_description=long_description, long_description_content_type='text/markdown', python_requires=">=3.7.0", - author='The Kivy team', + author='Kivy Team and other contributors', author_email='kivy-dev@googlegroups.com', url='https://github.com/kivy/python-for-android', license='MIT', @@ -121,9 +127,16 @@ def recursively_include(results, directory, patterns): 'Programming Language :: Python :: 3.8', 'Programming Language :: Python :: 3.9', 'Programming Language :: Python :: 3.10', + 'Programming Language :: Python :: 3.11', 'Topic :: Software Development', 'Topic :: Utilities', ], packages=packages, package_data=package_data, + project_urls={ + 'Documentation': "https://python-for-android.readthedocs.io", + 'Source': "https://github.com/kivy/python-for-android", + 'Bug Reports': "https://github.com/kivy/python-for-android/issues", + }, + )