Skip to content

Commit d139d8a

Browse files
committed
feat: support uv with Android
Signed-off-by: Henry Schreiner <[email protected]>
1 parent 3a52416 commit d139d8a

File tree

2 files changed

+18
-11
lines changed

2 files changed

+18
-11
lines changed

cibuildwheel/platforms/android.py

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434
from ..util.helpers import prepare_command
3535
from ..util.packaging import find_compatible_wheel
3636
from ..util.python_build_standalone import create_python_build_standalone_environment
37-
from ..venv import constraint_flags, virtualenv
37+
from ..venv import constraint_flags, find_uv, virtualenv
3838

3939

4040
def android_triplet(identifier: str) -> str:
@@ -187,6 +187,13 @@ def setup_env(
187187
* android_env, which uses the environment while simulating running on Android.
188188
"""
189189
log.step("Setting up build environment...")
190+
build_frontend = build_options.build_frontend.name
191+
use_uv = build_frontend == "build[uv]"
192+
uv_path = find_uv()
193+
if use_uv and uv_path is None:
194+
msg = "uv not found"
195+
raise AssertionError(msg)
196+
pip = ["pip"] if not use_uv else [str(uv_path), "pip"]
190197

191198
# Create virtual environment
192199
python_exe = create_python_build_standalone_environment(
@@ -197,14 +204,14 @@ def setup_env(
197204
version=config.version, tmp_dir=build_path
198205
)
199206
build_env = virtualenv(
200-
config.version, python_exe, venv_dir, dependency_constraint, use_uv=False
207+
config.version, python_exe, venv_dir, dependency_constraint, use_uv=use_uv
201208
)
202209
create_cmake_toolchain(config, build_path, python_dir, build_env)
203210

204211
# Apply custom environment variables, and check environment is still valid
205212
build_env = build_options.environment.as_dictionary(build_env)
206213
build_env["PIP_DISABLE_PIP_VERSION_CHECK"] = "1"
207-
for command in ["python", "pip"]:
214+
for command in ["python"] if use_uv else ["python", "pip"]:
208215
command_path = call("which", command, env=build_env, capture_stdout=True).strip()
209216
if command_path != f"{venv_dir}/bin/{command}":
210217
msg = (
@@ -219,11 +226,10 @@ def setup_env(
219226
android_env = setup_android_env(config, python_dir, venv_dir, build_env)
220227

221228
# Install build tools
222-
build_frontend = build_options.build_frontend
223-
if build_frontend.name != "build":
229+
if build_frontend not in {"build", "build[uv]"}:
224230
msg = "Android requires the build frontend to be 'build'"
225231
raise errors.FatalError(msg)
226-
call("pip", "install", "build", *constraint_flags(dependency_constraint), env=build_env)
232+
call(*pip, "install", "build", *constraint_flags(dependency_constraint), env=build_env)
227233

228234
# Build-time requirements must be queried within android_env, because
229235
# `get_requires_for_build` can run arbitrary code in setup.py scripts, which may be
@@ -243,13 +249,13 @@ def make_extra_environ(self) -> dict[str, str]:
243249

244250
pb = ProjectBuilder.from_isolated_env(AndroidEnv(), build_options.package_dir)
245251
if pb.build_system_requires:
246-
call("pip", "install", *pb.build_system_requires, env=build_env)
252+
call(*pip, "install", *pb.build_system_requires, env=build_env)
247253

248254
requires_for_build = pb.get_requires_for_build(
249255
"wheel", parse_config_settings(build_options.config_settings)
250256
)
251257
if requires_for_build:
252-
call("pip", "install", *requires_for_build, env=build_env)
258+
call(*pip, "install", *requires_for_build, env=build_env)
253259

254260
return build_env, android_env
255261

test/test_android.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -103,16 +103,17 @@ def test_expected_wheels(tmp_path):
103103
)
104104

105105

106-
def test_frontend_good(tmp_path):
106+
@pytest.mark.parametrize("frontend", ["build[uv]", "pip"])
107+
def test_frontend_good(tmp_path, frontend):
107108
new_c_project().generate(tmp_path)
108109
wheels = cibuildwheel_run(
109110
tmp_path,
110-
add_env={**cp313_env, "CIBW_BUILD_FRONTEND": "build"},
111+
add_env={**cp313_env, "CIBW_BUILD_FRONTEND": frontend},
111112
)
112113
assert wheels == [f"spam-0.1.0-cp313-cp313-android_21_{native_arch.android_abi}.whl"]
113114

114115

115-
@pytest.mark.parametrize("frontend", ["build[uv]", "pip"])
116+
@pytest.mark.parametrize("frontend", ["pip"])
116117
def test_frontend_bad(frontend, tmp_path, capfd):
117118
new_c_project().generate(tmp_path)
118119
with pytest.raises(CalledProcessError):

0 commit comments

Comments
 (0)