gh-116622: Add Android testbed (GH-117878)

Add code and config for a minimal Android app, and instructions to build and run it.
Improve Android build instructions in general.
Add a tool subcommand to download the Gradle wrapper (with its binary blob). Android
studio must be downloaded manually (due to the license).
This commit is contained in:
Malcolm Smith 2024-05-01 07:36:45 +01:00 committed by GitHub
parent 21336aa127
commit 2520eed0a5
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
19 changed files with 570 additions and 10 deletions

View file

@ -7,8 +7,9 @@ import shutil
import subprocess
import sys
import sysconfig
from os.path import relpath
from os.path import basename, relpath
from pathlib import Path
from tempfile import TemporaryDirectory
SCRIPT_NAME = Path(__file__).name
CHECKOUT = Path(__file__).resolve().parent.parent
@ -102,11 +103,17 @@ def unpack_deps(host):
for name_ver in ["bzip2-1.0.8-1", "libffi-3.4.4-2", "openssl-3.0.13-1",
"sqlite-3.45.1-0", "xz-5.4.6-0"]:
filename = f"{name_ver}-{host}.tar.gz"
run(["wget", f"{deps_url}/{name_ver}/{filename}"])
download(f"{deps_url}/{name_ver}/{filename}")
run(["tar", "-xf", filename])
os.remove(filename)
def download(url, target_dir="."):
out_path = f"{target_dir}/{basename(url)}"
run(["curl", "-Lf", "-o", out_path, url])
return out_path
def configure_host_python(context):
host_dir = subdir(context.host, clean=context.clean)
@ -160,6 +167,30 @@ def clean_all(context):
delete_if_exists(CROSS_BUILD_DIR)
# To avoid distributing compiled artifacts without corresponding source code,
# the Gradle wrapper is not included in the CPython repository. Instead, we
# extract it from the Gradle release.
def setup_testbed(context):
ver_long = "8.7.0"
ver_short = ver_long.removesuffix(".0")
testbed_dir = CHECKOUT / "Android/testbed"
for filename in ["gradlew", "gradlew.bat"]:
out_path = download(
f"https://raw.githubusercontent.com/gradle/gradle/v{ver_long}/{filename}",
testbed_dir)
os.chmod(out_path, 0o755)
with TemporaryDirectory(prefix=SCRIPT_NAME) as temp_dir:
os.chdir(temp_dir)
bin_zip = download(
f"https://services.gradle.org/distributions/gradle-{ver_short}-bin.zip")
outer_jar = f"gradle-{ver_short}/lib/plugins/gradle-wrapper-{ver_short}.jar"
run(["unzip", bin_zip, outer_jar])
run(["unzip", "-o", "-d", f"{testbed_dir}/gradle/wrapper", outer_jar,
"gradle-wrapper.jar"])
def main():
parser = argparse.ArgumentParser()
subcommands = parser.add_subparsers(dest="subcommand")
@ -173,8 +204,11 @@ def main():
help="Run `configure` for Android")
make_host = subcommands.add_parser("make-host",
help="Run `make` for Android")
clean = subcommands.add_parser("clean", help="Delete files and directories "
"created by this script")
subcommands.add_parser(
"clean", help="Delete the cross-build directory")
subcommands.add_parser(
"setup-testbed", help="Download the testbed Gradle wrapper")
for subcommand in build, configure_build, configure_host:
subcommand.add_argument(
"--clean", action="store_true", default=False, dest="clean",
@ -194,7 +228,8 @@ def main():
"configure-host": configure_host_python,
"make-host": make_host_python,
"build": build_all,
"clean": clean_all}
"clean": clean_all,
"setup-testbed": setup_testbed}
dispatch[context.subcommand](context)