Skip to content

Commit cabe9ec

Browse files
committed
Move Android build and prefix directories from cross-build to Android
1 parent f819900 commit cabe9ec

File tree

5 files changed

+59
-47
lines changed

5 files changed

+59
-47
lines changed

Android/.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
/build
2+
/dist
3+
/prefix

Android/README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -60,8 +60,8 @@ To do all steps in a single command, run:
6060
./android.py build HOST
6161
```
6262

63-
In the end you should have a build Python in `cross-build/build`, and an Android
64-
build in `cross-build/HOST`.
63+
In the end you should have an Android build of Python and its supporting
64+
libraries in `prefix/HOST`.
6565

6666
You can use `--` as a separator for any of the `configure`-related commands –
6767
including `build` itself – to pass arguments to the underlying `configure`
@@ -80,7 +80,7 @@ The test suite can be run on Linux, macOS, or Windows:
8080
* On Linux, the emulator needs access to the KVM virtualization interface, and
8181
a DISPLAY environment variable pointing at an X server.
8282
* On Windows, you won't be able to do the build on the same machine, so you'll
83-
have to copy the `cross-build/HOST` directory from somewhere else.
83+
have to copy the `prefix/HOST` directory from somewhere else.
8484

8585
The test suite can usually be run on a device with 2 GB of RAM, but this is
8686
borderline, so you may need to increase it to 4 GB. As of Android

Android/android.py

Lines changed: 35 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,12 @@
2222
SCRIPT_NAME = Path(__file__).name
2323
CHECKOUT = Path(__file__).resolve().parent.parent
2424
ANDROID_DIR = CHECKOUT / "Android"
25+
BUILD_DIR = ANDROID_DIR / "build"
26+
DIST_DIR = ANDROID_DIR / "dist"
27+
PREFIX_DIR = ANDROID_DIR / "prefix"
2528
TESTBED_DIR = ANDROID_DIR / "testbed"
26-
CROSS_BUILD_DIR = CHECKOUT / "cross-build"
2729

30+
HOSTS = ["aarch64-linux-android", "x86_64-linux-android"]
2831
APP_ID = "org.python.testbed"
2932
DECODE_ARGS = ("UTF-8", "backslashreplace")
3033

@@ -58,12 +61,10 @@ def delete_glob(pattern):
5861
path.unlink()
5962

6063

61-
def subdir(name, *, clean=None):
62-
path = CROSS_BUILD_DIR / name
63-
if clean:
64-
delete_glob(path)
64+
def subdir(parent, host, *, create=False):
65+
path = parent / host
6566
if not path.exists():
66-
if clean is None:
67+
if not create:
6768
sys.exit(
6869
f"{path} does not exist. Create it by running the appropriate "
6970
f"`configure` subcommand of {SCRIPT_NAME}.")
@@ -83,7 +84,7 @@ def run(command, *, host=None, env=None, log=True, **kwargs):
8384
env_output = subprocess.run(
8485
f"set -eu; "
8586
f"HOST={host}; "
86-
f"PREFIX={subdir(host)}/prefix; "
87+
f"PREFIX={subdir(PREFIX_DIR, host)}; "
8788
f". {env_script}; "
8889
f"export",
8990
check=True, shell=True, text=True, stdout=subprocess.PIPE
@@ -111,19 +112,21 @@ def run(command, *, host=None, env=None, log=True, **kwargs):
111112

112113
def build_python_path():
113114
"""The path to the build Python binary."""
114-
build_dir = subdir("build")
115-
binary = build_dir / "python"
115+
build_subdir = subdir(BUILD_DIR, "build")
116+
binary = build_subdir / "python"
116117
if not binary.is_file():
117118
binary = binary.with_suffix(".exe")
118119
if not binary.is_file():
119120
raise FileNotFoundError("Unable to find `python(.exe)` in "
120-
f"{build_dir}")
121+
f"{build_subdir}")
121122

122123
return binary
123124

124125

125126
def configure_build_python(context):
126-
os.chdir(subdir("build", clean=context.clean))
127+
if context.clean:
128+
clean("build")
129+
os.chdir(subdir(BUILD_DIR, "build", create=True))
127130

128131
command = [relpath(CHECKOUT / "configure")]
129132
if context.args:
@@ -132,7 +135,7 @@ def configure_build_python(context):
132135

133136

134137
def make_build_python(context):
135-
os.chdir(subdir("build"))
138+
os.chdir(subdir(BUILD_DIR, "build"))
136139
run(["make", "-j", str(os.cpu_count())])
137140

138141

@@ -153,17 +156,16 @@ def download(url, target_dir="."):
153156

154157

155158
def configure_host_python(context):
156-
host_dir = subdir(context.host, clean=context.clean)
159+
if context.clean:
160+
clean(context.host)
157161

158-
prefix_dir = host_dir / "prefix"
159-
if not prefix_dir.exists():
160-
prefix_dir.mkdir()
161-
os.chdir(prefix_dir)
162+
prefix_subdir = subdir(PREFIX_DIR, context.host, create=True)
163+
if not (prefix_subdir / "include").exists():
164+
os.chdir(prefix_subdir)
162165
unpack_deps(context.host)
163166

164-
build_dir = host_dir / "build"
165-
build_dir.mkdir(exist_ok=True)
166-
os.chdir(build_dir)
167+
build_subdir = subdir(BUILD_DIR, context.host, create=True)
168+
os.chdir(build_subdir)
167169

168170
command = [
169171
# Basic cross-compiling configuration
@@ -179,7 +181,7 @@ def configure_host_python(context):
179181

180182
# Dependent libraries. The others are found using pkg-config: see
181183
# android-env.sh.
182-
f"--with-openssl={prefix_dir}",
184+
f"--with-openssl={prefix_subdir}",
183185
]
184186

185187
if context.args:
@@ -191,15 +193,13 @@ def make_host_python(context):
191193
# The CFLAGS and LDFLAGS set in android-env include the prefix dir, so
192194
# delete any previous Python installation to prevent it being used during
193195
# the build.
194-
host_dir = subdir(context.host)
195-
prefix_dir = host_dir / "prefix"
196-
delete_glob(f"{prefix_dir}/include/python*")
197-
delete_glob(f"{prefix_dir}/lib/libpython*")
198-
delete_glob(f"{prefix_dir}/lib/python*")
196+
prefix_subdir = subdir(PREFIX_DIR, context.host)
197+
for pattern in ("include/python*", "lib/libpython*", "lib/python*"):
198+
delete_glob(f"{prefix_subdir}/{pattern}")
199199

200-
os.chdir(host_dir / "build")
200+
os.chdir(subdir(BUILD_DIR, context.host))
201201
run(["make", "-j", str(os.cpu_count())], host=context.host)
202-
run(["make", "install", f"prefix={prefix_dir}"], host=context.host)
202+
run(["make", "install", f"prefix={prefix_subdir}"], host=context.host)
203203

204204

205205
def build_all(context):
@@ -209,8 +209,14 @@ def build_all(context):
209209
step(context)
210210

211211

212+
def clean(host):
213+
for parent in (BUILD_DIR, PREFIX_DIR):
214+
delete_glob(f"{parent}/{host}")
215+
216+
212217
def clean_all(context):
213-
delete_glob(CROSS_BUILD_DIR)
218+
for parent in (BUILD_DIR, PREFIX_DIR):
219+
delete_glob(parent)
214220

215221

216222
def setup_sdk():

Android/testbed/app/build.gradle.kts

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,24 +7,26 @@ plugins {
77
}
88

99
val PYTHON_DIR = file("../../..").canonicalPath
10-
val PYTHON_CROSS_DIR = "$PYTHON_DIR/cross-build"
10+
val ANDROID_DIR = "$PYTHON_DIR/Android"
11+
val PREFIX_DIR = "$ANDROID_DIR/prefix"
1112

1213
val ABIS = mapOf(
1314
"arm64-v8a" to "aarch64-linux-android",
1415
"x86_64" to "x86_64-linux-android",
15-
).filter { file("$PYTHON_CROSS_DIR/${it.value}").exists() }
16+
).filter { file("$PREFIX_DIR/${it.value}").exists() }
1617
if (ABIS.isEmpty()) {
1718
throw GradleException(
18-
"No Android ABIs found in $PYTHON_CROSS_DIR: see Android/README.md " +
19+
"No Android ABIs found in $PREFIX_DIR: see Android/README.md " +
1920
"for building instructions."
2021
)
2122
}
2223

23-
val PYTHON_VERSION = file("$PYTHON_DIR/Include/patchlevel.h").useLines {
24-
for (line in it) {
25-
val match = """#define PY_VERSION\s+"(\d+\.\d+)""".toRegex().find(line)
24+
val PYTHON_VERSION = run {
25+
val includeDir = file("$PREFIX_DIR/${ABIS.values.iterator().next()}/include")
26+
for (filename in includeDir.list()!!) {
27+
val match = """python(\d+\.\d+)""".toRegex().matchEntire(filename)
2628
if (match != null) {
27-
return@useLines match.groupValues[1]
29+
return@run match.groupValues[1]
2830
}
2931
}
3032
throw GradleException("Failed to find Python version")
@@ -55,7 +57,7 @@ android {
5557

5658
ndk.abiFilters.addAll(ABIS.keys)
5759
externalNativeBuild.cmake.arguments(
58-
"-DPYTHON_CROSS_DIR=$PYTHON_CROSS_DIR",
60+
"-DPYTHON_PREFIX_DIR=$PREFIX_DIR",
5961
"-DPYTHON_VERSION=$PYTHON_VERSION",
6062
"-DANDROID_SUPPORT_FLEXIBLE_PAGE_SIZES=ON",
6163
)
@@ -136,9 +138,10 @@ androidComponents.onVariants { variant ->
136138
val pyPlusVer = "python$PYTHON_VERSION"
137139
generateTask(variant, variant.sources.assets!!) {
138140
into("python") {
141+
// Include files such as pyconfig.h are used by some of the tests.
139142
into("include/$pyPlusVer") {
140143
for (triplet in ABIS.values) {
141-
from("$PYTHON_CROSS_DIR/$triplet/prefix/include/$pyPlusVer")
144+
from("$PREFIX_DIR/$triplet/include/$pyPlusVer")
142145
}
143146
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
144147
}
@@ -147,10 +150,10 @@ androidComponents.onVariants { variant ->
147150
// To aid debugging, the source directory takes priority.
148151
from("$PYTHON_DIR/Lib")
149152

150-
// The cross-build directory provides ABI-specific files such as
153+
// The predix directory provides ABI-specific files such as
151154
// sysconfigdata.
152155
for (triplet in ABIS.values) {
153-
from("$PYTHON_CROSS_DIR/$triplet/prefix/lib/$pyPlusVer")
156+
from("$PREFIX_DIR/$triplet/lib/$pyPlusVer")
154157
}
155158

156159
into("site-packages") {
@@ -166,7 +169,7 @@ androidComponents.onVariants { variant ->
166169
generateTask(variant, variant.sources.jniLibs!!) {
167170
for ((abi, triplet) in ABIS.entries) {
168171
into(abi) {
169-
from("$PYTHON_CROSS_DIR/$triplet/prefix/lib")
172+
from("$PREFIX_DIR/$triplet/lib")
170173
include("libpython*.*.so")
171174
include("lib*_python.so")
172175
}
Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
cmake_minimum_required(VERSION 3.4.1)
22
project(testbed)
33

4-
set(PREFIX_DIR ${PYTHON_CROSS_DIR}/${CMAKE_LIBRARY_ARCHITECTURE}/prefix)
5-
include_directories(${PREFIX_DIR}/include/python${PYTHON_VERSION})
6-
link_directories(${PREFIX_DIR}/lib)
4+
set(PYTHON_PREFIX_SUBDIR ${PYTHON_PREFIX_DIR}/${CMAKE_LIBRARY_ARCHITECTURE})
5+
include_directories(${PYTHON_PREFIX_SUBDIR}/include/python${PYTHON_VERSION})
6+
link_directories(${PYTHON_PREFIX_SUBDIR}/lib)
77
link_libraries(log python${PYTHON_VERSION})
88

99
add_library(main_activity SHARED main_activity.c)

0 commit comments

Comments
 (0)