Skip to content

Commit 2cb8080

Browse files
committed
ENH: Add support for targeting Android
1 parent 3205db1 commit 2cb8080

2 files changed

Lines changed: 49 additions & 0 deletions

File tree

mesonpy/__init__.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -744,6 +744,27 @@ def __init__(
744744
self._meson_cross_file.write_text(cross_file_data, encoding='utf-8')
745745
self._meson_args['setup'].extend(('--cross-file', os.fspath(self._meson_cross_file)))
746746

747+
# Android requires cross compilation: synthesize the appropriate cross file.
748+
elif sysconfig.get_platform().startswith('android-'):
749+
cross_file_data = textwrap.dedent(f'''
750+
# Binaries are controlled by environment variables, so they don't need
751+
# to be repeated here.
752+
[host_machine]
753+
system = 'android'
754+
subsystem = 'android'
755+
kernel = 'linux'
756+
cpu = {platform.machine()!r}
757+
cpu_family = {platform.machine()!r}
758+
endian = {sys.byteorder!r}
759+
760+
[properties]
761+
# cibuildwheel's cross virtual environment will make Meson believe it's
762+
# running on Android when it's actually running on Linux or macOS.
763+
needs_exe_wrapper = true
764+
''')
765+
self._meson_cross_file.write_text(cross_file_data, encoding='utf-8')
766+
self._meson_args['setup'].extend(('--cross-file', os.fspath(self._meson_cross_file)))
767+
747768
# Support iOS targets. iOS does not have native build tools and always
748769
# requires cross compilation: synthesize the appropriate cross file.
749770
elif sysconfig.get_platform().startswith('ios-'):

tests/test_project.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -378,6 +378,34 @@ def test_archflags_envvar_parsing_invalid(package_purelib_and_platlib, monkeypat
378378
os.environ.pop('_PYTHON_HOST_PLATFORM', None)
379379

380380

381+
def test_android_project(package_simple, monkeypatch, tmp_path):
382+
# Mock being on Android
383+
monkeypatch.setattr(sys, 'platform', 'android')
384+
monkeypatch.setattr(sys, 'byteorder', 'little')
385+
monkeypatch.setattr(platform, 'machine', Mock(return_value='aarch64'))
386+
monkeypatch.setattr(sysconfig, 'get_platform', Mock(return_value='android-24-arm64_v8a'))
387+
monkeypatch.setenv('STRIP', '/path/to/strip')
388+
389+
# Create a project.
390+
project = mesonpy.Project(source_dir=package_simple, build_dir=tmp_path)
391+
392+
# Meson configuration points at the cross file
393+
assert project._meson_args['setup'][-2:] == ['--cross-file', os.fspath(tmp_path / 'meson-python-cross-file.ini')]
394+
395+
# Meson config files exist, and have some relevant keys
396+
assert (tmp_path / 'meson-python-native-file.ini').exists()
397+
assert (tmp_path / 'meson-python-cross-file.ini').exists()
398+
399+
cross_config = (tmp_path / 'meson-python-cross-file.ini').read_text().splitlines()
400+
assert "system = 'android'" in cross_config
401+
assert "subsystem = 'android'" in cross_config
402+
assert "kernel = 'linux'" in cross_config
403+
assert "cpu = 'aarch64'" in cross_config
404+
assert "cpu_family = 'aarch64'" in cross_config
405+
assert "endian = 'little'" in cross_config
406+
assert 'needs_exe_wrapper = true' in cross_config
407+
408+
381409
@pytest.mark.skipif(sys.version_info < (3, 13), reason='requires Python 3.13 or higher')
382410
@pytest.mark.parametrize('multiarch', [
383411
'arm64-iphoneos',

0 commit comments

Comments
 (0)