Skip to content
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

bpo-30386: Add a build infrastructure for Android. #1629

Closed
wants to merge 51 commits into from
Closed

bpo-30386: Add a build infrastructure for Android. #1629

wants to merge 51 commits into from

Conversation

xdegaye
Copy link
Contributor

@xdegaye xdegaye commented May 17, 2017

Add a build infrastructure for Android to cross-compile Python using the Android NDK and allowing to run python interactively on the emulator or to run the Python test suite using the Android SDK.

https://bugs.python.org/issue30386

@xdegaye xdegaye added the type-feature A feature request or enhancement label May 17, 2017
@xdegaye xdegaye self-assigned this May 17, 2017
@AraHaan
Copy link
Contributor

AraHaan commented May 17, 2017

Mind also doing this for iOS as well so people can build their own free version of python for the iOS. It is annoying having to pay $$$ for 3.4+ on it but nothing for 2.7...

Also what about pip on the android and iOS? I thought they might not get pip to work on them.

@ned-deily ned-deily self-requested a review May 24, 2017 23:50
@xdegaye
Copy link
Contributor Author

xdegaye commented May 30, 2017

Commit details can be found at issue bpo-30386.

@xdegaye xdegaye requested a review from tiran as a code owner August 8, 2017 16:50
@xdegaye
Copy link
Contributor Author

xdegaye commented Aug 8, 2017

xdegaye requested a review from tiran as a code owner 5 hours ago

I did not request a review from tiran.

@xdegaye xdegaye removed the request for review from tiran August 8, 2017 21:50
@pmp-p
Copy link
Contributor

pmp-p commented Nov 17, 2017

@xdegaye is there some dedicated place to discuss about android ports since you are not on irc ?

@xdegaye
Copy link
Contributor Author

xdegaye commented Nov 17, 2017

@pmp-p you can open a new issue on the issue tracker and if you want to involve me in the discussion just add xdegaye to the nosy list of this issue, or you can send an email to python-ideas or python-dev.
It depends of what you want to discuss.

.. contents::

This document provides a quick overview of the Python build system for Android
on a **linux platform** [1]_.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This documentation is uncomplete. You need "quick start" instructions to explain what is Android, what do I require on my local host, do I need a physical device, etc. This documentation mostly explains the implementation, not really how to use it.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm trying to run Python on Android in an emulator using these recipes, but it's hard to understand how to use it. First, I downloaded NDK r16b but configure-android immediately fails because it requires NDK 14... This thing be very explicit in the doc, since the NDK is a big file (800 MB, so slow to download) and takes a lot of disk space (2.6 GB). It's not easy to install it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will add a quick start section shortly.

First, I downloaded NDK r16b but configure-android immediately fails because it requires NDK 14.

I understand your frustation. The README does say that android-ndk-r14 is required in a note and that note is referred to in each Requirements section where the NDK is required. I will add a warning about this in the quick start section unless you have a better idea.

@bedevere-bot
Copy link

When you're done making the requested changes, leave the comment: I have made the requested changes; please review again.

@vstinner
Copy link
Member

I did not request a review from tiran.

See .github/CODEOWNERS: some maintainers are automatically added depending which files are modified.

@vstinner
Copy link
Member

I tried to use the recipe but I failed. There many traps:

  • NDK 14 is required, whereas Android website first proposes NDK 16
  • NDK 14 requires ncurses5 whereas Fedora 27 uses ncurses6: "dnf install ncurses-compat-libs" is needed on Fedora 27
  • Python 3.7 must be installed on the system, available in the PATH

I tried:

cd Android
../configure-android  PYTHON_FOR_BUILD=/opt/py37/bin/python3.7
make

The compilation fails somewhere in setup.py about Tools/. I commented Tools in setup.py, then the compilation fails on building something about extensions:

vstinner@apu$ make
running build
running build_ext
Traceback (most recent call last):
  File "/home/vstinner/prog/python/master/setup.py", line 2310, in <module>
    main()
  File "/home/vstinner/prog/python/master/setup.py", line 2299, in main
    ext_modules=[Extension('_struct', ['_struct.c'])]
  File "/opt/py37/lib/python3.7/distutils/core.py", line 148, in setup
    dist.run_commands()
  File "/opt/py37/lib/python3.7/distutils/dist.py", line 966, in run_commands
    self.run_command(cmd)
  File "/opt/py37/lib/python3.7/distutils/dist.py", line 985, in run_command
    cmd_obj.run()
  File "/opt/py37/lib/python3.7/distutils/command/build.py", line 135, in run
    self.run_command(cmd_name)
  File "/opt/py37/lib/python3.7/distutils/cmd.py", line 313, in run_command
    self.distribution.run_command(command)
  File "/opt/py37/lib/python3.7/distutils/dist.py", line 985, in run_command
    cmd_obj.run()
  File "/opt/py37/lib/python3.7/distutils/command/build_ext.py", line 339, in run
    self.build_extensions()
  File "/home/vstinner/prog/python/master/setup.py", line 251, in build_extensions
    for filename in self.distribution.scripts]
TypeError: 'NoneType' object is not iterable

@vstinner
Copy link
Member


  File "/home/vstinner/prog/python/master/setup.py", line 251, in build_extensions
    for filename in self.distribution.scripts]
TypeError: 'NoneType' object is not iterable

Ah! This is caused by my setup.py hack. The correct patch is:

diff --git a/setup.py b/setup.py
index 09e35e5060..965d7d58fd 100644
--- a/setup.py
+++ b/setup.py
@@ -2301,8 +2301,7 @@ def main():
           # If you change the scripts installed here, you also need to
           # check the PyBuildScripts command above, and change the links
           # created by the bininstall target in Makefile.pre.in
-          scripts = ["Tools/scripts/pydoc3", "Tools/scripts/idle3",
-                     "Tools/scripts/2to3", "Tools/scripts/pyvenv"]
+          scripts = []
         )
 
 # --install-platlib

With this patch, I'm able to build Python:

Python build finished successfully!

Ok. Now what I am supposed to do? :-)

@vstinner
Copy link
Member

My notes:

Quick Start
===========

Main steps:

* Download NDK and Android x86 VM ISO
* Compile Python 3.7 on the host
* Install NDK
* Cross-Compile Python to Android
* Create an Android VM
* Copy the ELF ./python binary to the VM
* Start the VM, run ./python

Requirements:

* Fedora 27
* qemu
* 3 GB disk space at least: NDK (2.6 GB) + 400 MB of Python build objects + 700 MB ISO file

Download:

* Dowload NDK 14 from https://developer.android.com/ndk/downloads/index.html -- NDK 14 is an old version, don't pick the most recent!
* Download android-x86_64-6.0-r3.iso from http://www.android-x86.org/download

Instructions.

* NDK: toolchains + platforms, 800 MiB download, 2.6 GB uncompressed
* Agree with the Android Terms and Conditions
* Download android-ndk-r14: Apache license, 813 MB


Compile Python 3.7 on the host::

  ./configure --prefix /opt/py37
  make
  make install

Install NDK::

  mkdir -p /opt/android
  unzip android-ndk-r16b-linux-x86_64.zip -d /opt/android
  export ANDROID_NDK_ROOT=/opt/android/android-ndk-r14b

  sudo dnf install ncurses-compat-libs # Fedora
  # ArchLinux: https://aur.archlinux.org/packages/android-ndk/

Fix setup.py::

  diff --git a/setup.py b/setup.py
  index 09e35e5060..965d7d58fd 100644
  --- a/setup.py
  +++ b/setup.py
  @@ -2301,8 +2301,7 @@ def main():
             # If you change the scripts installed here, you also need to
             # check the PyBuildScripts command above, and change the links
             # created by the bininstall target in Makefile.pre.in
  -          scripts = ["Tools/scripts/pydoc3", "Tools/scripts/idle3",
  -                     "Tools/scripts/2to3", "Tools/scripts/pyvenv"]
  +          scripts = []
           )

   # --install-platlib

Cross-compile::

  cd Android
  ../configure-android --with-pydebug PYTHON_FOR_BUILD=/opt/py37/bin/python3.7
  make

@pmp-p
Copy link
Contributor

pmp-p commented Dec 12, 2017

Hi, first thx for layout some android support.

linux mint 18.3 : ANDROID_ARCH=armv7 ANDROID_API=21
ANDROID_NDK_ROOT set to ndk 14b

restrictions of WITH_LIBRARIES="libffi" cause make install to fail because no .so get generated and build.mk tries to copy and package them ( libffi is static .a scripts looks for .so ).

btw curses build fails with : ../ncurses/./tty/hardscroll.c:148:10: fatal error: 'curses.priv.h' file not found
side note android libs are not numbered libpython :
patchelf --print-soname libpython3.7m.so => libpython3.7m.so.1.0 shoud be libpython3.7m.so

@xdegaye
Copy link
Contributor Author

xdegaye commented Dec 12, 2017

@vstinner

Ok. Now what I am supposed to do? :-)

Sorry but you did it wrong :-(. To build Python for an emulator you must follow the Build for the emulator with makesetup section of the README. Do not run configure-android directly, this script is run by the Makefile created by makesetup.

So you follow these steps:

  • Install the NDK.
  • Install the SDK (check the requirements for disk space). The SDK contains qemu so no need to install it and it contains the images for the architectures that you are downloading with the sdkmanager command so the Android x86 VM ISO image is not needed.
  • Run makesetup to create the Makefile and refer to the section Makefile targets for the description of the Makefile targets.
  • Run make build. This target compiles Python 3.7 natively (it is not necessary to do it yourself) and cross-compiles the external libraries and Python.
  • Run make install. This target makes a distribution, creates the AVD, starts the emulator, installs python and runs a remote shell. Creation of the AVD takes quite a long time and is done only once.

I think the Cross-compilation with configure-android section should be removed, it is confusing.

@xdegaye
Copy link
Contributor Author

xdegaye commented Dec 12, 2017

@pmp-p Are you using the external libraries that are downloaded by the Makefile generated by makesetup and are they built by this Makefile ?
In the case where the answer is yes to both questions, can you please attach the full output of the build.

@pmp-p
Copy link
Contributor

pmp-p commented Dec 12, 2017

yes & yes : here's full session, https://gist.githubusercontent.com/pmp-p/84e93c3e13943ea61e5a3493debf23de/raw/5696180869ccee445c47af9b07d0f3c67d8f6d6d/gistfile1.txt

and if it can help to broad support, i tried cross compilation too for api-19 at the time of 3.7a2 i got repl, interpreter to embed /run panda3d both on H3Droid armv7 : here are some ugly patches https://github.com/pmp-p/h3droid/tree/sdk/usr/src/python3.7-android/patches

@xdegaye
Copy link
Contributor Author

xdegaye commented Dec 13, 2017

@pmp-p

yes & yes

Are you sure ?

  • The ncurses compilation recipe that fails in your build starts with cd ../obj_s; and there is no such statement anywhere in the Makefile generated from the ncurses sources downloaded by this build system (and of course the cd ../obj_s; statement does not show up when reproducing the build with your command line arguments). And BTW thanks for having me lose my time searching for this.
  • It is not possible that the problem that you have reported in your previous post about libffi may occur unless this build system has been modified.

@pmp-p
Copy link
Contributor

pmp-p commented Dec 13, 2017

( "BTW thanks for having me lose my time searching for this." Then please for god's sake don't make android support official if this is the kind of help or welcome we ( poor users) would get. )

Of course i am sure , i took the time to build a clean mint 18 pc to run the build side by side with victor he was building api-24 64bits, while me api-21 32bits.

Parenthèses fermées j'espère.

PS: by reviewing irc log, it appears Victor had it built for intel/amd, not arm like me maybe that's a clue
"It is not possible" => impossible n'est pas français donc si ;)

@xdegaye
Copy link
Contributor Author

xdegaye commented Dec 14, 2017

This is the full build.log of a build that uses the same parameters as those used by @pmp-p. The differences with @pmp-p results are:

  • The build is SUCCESSFUL.
  • libffi source is downloaded and built.
  • readline source is downloaded (which is not the case with the build output reported by @pmp-p, the origin of the readline source is unknown) and successfully built.

BTW still missing the build output of the other problem reported @pmp-p.

@pmp-p
Copy link
Contributor

pmp-p commented Dec 14, 2017

"the origin of the readline source is unknown" it is always the case since you are using multiple external link .tar.gz without checking checksums. In some case that could be a concern at least for some devices and average system administrator.

You are using ccache and may have curses-dev installed so i did the same, checked both using mawk/gawk => but problem was still there.

For me it is quite simple : ncurses cross compile support is not as good as expected and need controlled environnement or a script of yours to help it.

Sadly i tried on ubuntu flavor because that is what less than average unix developper is using nowadays.
i suggest you set only libffi by default and sanitize environnement before building deps.

i'll post make install log failure when make depends step is fixed, as i adopted your script for a panda3d android build process : i'll try to investigate more.

@pmp-p
Copy link
Contributor

pmp-p commented Jan 21, 2018

Well i upgraded my system recently, and the ncurses build problem is gone, so let's forget about it.

But some questions arose ...

CPython compiles fines with any ndk : only third parties have real trouble, so why introduce them ?

Are you removing older api and other ndk just because you know some tests won't run ?

As running/embedding/testing is a different problem and is not limited to "api-21 ndk-14 on friendly host" now i get it : that's not android platform support of any kind so i owe you an apology because i was confused about that ( maybe false hope ),

I suggest you rename the title to "add a build infrastucture for 1 specific Android version where all third parties are not completely broken" and i wanted to thank you for your work it was very helpfull for a specific use case.

@inclement
Copy link

inclement commented Sep 18, 2018

I just tested this PR for use with Kivy via python-for-android, something I've been meaning to do for a long time, and it worked very well. I was also able to get target API 27 with the latest NDK 17 working without too many issues, although I don't really understand why some things did seem to break.

I found the python-dev mailing list posts about this but I'm not clear what is the current status of these efforts. Is this still the most up to date and active CPython for Android resource, or is there anything more recent, or likely to come soon? This PR already makes a superb base for improving python-for-android's Python 3 support, but I'd like to try to engage more with current developments if possible.

@xdegaye
Copy link
Contributor Author

xdegaye commented Sep 19, 2018

@inclement
I have made some changes to this PR few months ago that address Victor's review but did not push them here. I am not a core developer anymore and Victor has stated in two different issues that he is not interested anymore in Android, so it seems that it would be better to ask these questions on python-dev.

@xdegaye xdegaye closed this Dec 10, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
awaiting changes type-feature A feature request or enhancement
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants