Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
3 changes: 2 additions & 1 deletion server/pypi/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,8 @@ these can be installed using your distribution. Some of them have special entrie
[here](https://github.com/mzakharo/android-gfortran/releases/tag/r21e). Create a
`fortran` subdirectory in the same directory as this README, and unpack the .bz2 files
into it.
* `rust`: `rustup` must be on the PATH.
* `rust`: `rustup` must be on the PATH. One can set `PYO3_NO_PYTHON=1` in `script_env:` to build without a Python interpreter (https://pyo3.rs/main/building-and-distribution#building-abi3-extensions-without-a-python-interpreter).
Building with a Python interpreter is supported only for Python 3.13 and above.


## Building a package
Expand Down
29 changes: 20 additions & 9 deletions server/pypi/build-wheel.py
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@ def unpack_and_build(self):
self.src_dir = f"{self.build_dir}/src"
self.build_env = f"{self.build_dir}/env"
self.host_env = f"{self.build_dir}/requirements"
self.chaquopy_dir = f"{self.host_env}/chaquopy"

if self.no_unpack:
log("Reusing existing build directory due to --no-unpack")
Expand Down Expand Up @@ -249,6 +250,10 @@ def version_key(ver):
if len(zips) != 1:
raise CommandError(f"Found {len(zips)} {self.abi} ZIPs in {target_version_dir}")
self.target_zip = zips[0]
zips = glob(f"{target_version_dir}/target-*-stdlib.zip")
if len(zips) != 1:
raise CommandError(f"Found {len(zips)} stdlib ZIPs in {target_version_dir}")
self.std_lib_zip = zips[0]

def create_build_env(self):
python_ver = self.python or ".".join(map(str, sys.version_info[:2]))
Expand Down Expand Up @@ -507,9 +512,11 @@ def create_dummy_libs(self):
for name in ["pthread", "rt"]:
run(f"{os.environ['AR']} rc {self.host_env}/chaquopy/lib/lib{name}.a")

def extract_stdlib(self):
run(f"unzip -q -d {self.chaquopy_dir}/lib {self.std_lib_zip}")

def extract_target(self):
chaquopy_dir = f"{self.host_env}/chaquopy"
run(f"unzip -q -d {chaquopy_dir} {self.target_zip} include/* jniLibs/*")
run(f"unzip -q -d {self.chaquopy_dir} {self.target_zip} include/* jniLibs/*")

# Only include OpenSSL and SQLite in the environment if the recipe requests
# them. This affects grpcio, which provides its own copy of BoringSSL, and gets
Expand All @@ -522,7 +529,7 @@ def extract_target(self):
self.meta["requirements"]["host"].remove(name)
except ValueError:
for pattern in [f"include/{includes}", f"jniLibs/{self.abi}/{libs}"]:
run(f"rm -r {chaquopy_dir}/{pattern}", shell=True)
run(f"rm -r {self.chaquopy_dir}/{pattern}", shell=True)

# When building packages that could be loaded by older versions of Chaquopy,
# i.e non-Python packages, and Python packages for 3.12 and older:
Expand All @@ -538,7 +545,7 @@ def extract_target(self):
#
# When building only for Python 3.13 and newer, we should use the _python suffix
# so our wheels are compatible with any other Python on Android distributions.
lib_dir = f"{chaquopy_dir}/jniLibs/{self.abi}"
lib_dir = f"{self.chaquopy_dir}/jniLibs/{self.abi}"
for name in ["crypto", "ssl", "sqlite3"]:
python_name = f"lib{name}_python.so"
chaquopy_name = f"lib{name}_chaquopy.so"
Expand All @@ -552,8 +559,10 @@ def extract_target(self):
run(f"patchelf --set-soname {chaquopy_name} "
f"{lib_dir}/{chaquopy_name}")

run(f"mv {chaquopy_dir}/jniLibs/{self.abi}/* {chaquopy_dir}/lib", shell=True)
run(f"rm -r {chaquopy_dir}/jniLibs")
run(f"mv {self.chaquopy_dir}/jniLibs/{self.abi}/* {self.chaquopy_dir}/lib", shell=True)
run(f"rm -r {self.chaquopy_dir}/jniLibs")

self.extract_stdlib()

def build_with_script(self, build_script):
prefix_dir = f"{self.build_dir}/prefix"
Expand Down Expand Up @@ -672,7 +681,8 @@ def get_rust_env_vars(self, env):
# compatibility version via one of the "abi3-py*" features (e.g.
# abi3-py310). Doing this requires the "-L native" flag in RUSTFLAGS above.
# https://pyo3.rs/main/building-and-distribution#building-abi3-extensions-without-a-python-interpreter
"PYO3_NO_PYTHON": "1",
# "PYO3_NO_PYTHON": "1",
"PYO3_CROSS_LIB_DIR": self.chaquopy_dir,
"PYO3_CROSS": "1",
"PYO3_CROSS_PYTHON_VERSION": self.python,
})
Expand All @@ -691,8 +701,6 @@ def env_vars(self):

if self.needs_python:
self.get_python_env_vars(env, pypi_env)
if "rust" in self.non_python_build_reqs:
self.get_rust_env_vars(env)

env.update({
# TODO: make everything use HOST instead, and remove this.
Expand All @@ -712,6 +720,9 @@ def env_vars(self):
key, value = var.split("=", 1)
env[key] = value

if "rust" in self.non_python_build_reqs:
self.get_rust_env_vars(env)

# We do this unconditionally, because we don't know whether the package requires
# CMake (it may be listed in the pyproject.toml build-system requires).
self.generate_cmake_toolchain(env)
Expand Down
4 changes: 4 additions & 0 deletions server/pypi/packages/cryptography/meta.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@ package:
name: cryptography
version: "42.0.8"

build:
script_env:
- PYO3_NO_PYTHON=1

requirements:
build:
- rust
Expand Down
9 changes: 9 additions & 0 deletions server/pypi/packages/pydantic-core/meta.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package:
name: pydantic-core
version: "2.41.5"

requirements:
build:
- rust
host:
- python