Skip to content

Commit 3a80d89

Browse files
committed
WIP: ENH: implement support for build-details.json (PEP 739)
1 parent d8ed599 commit 3a80d89

2 files changed

Lines changed: 43 additions & 14 deletions

File tree

mesonpy/__init__.py

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -312,11 +312,15 @@ def __init__(
312312
manifest: Dict[str, List[Tuple[pathlib.Path, str]]],
313313
limited_api: bool,
314314
allow_windows_shared_libs: bool,
315+
is_cross: bool,
316+
build_details: Optional[Dict[str, str | Dict[str, Any]]] = None,
315317
) -> None:
316318
self._metadata = metadata
317319
self._manifest = manifest
318320
self._limited_api = limited_api
319321
self._allow_windows_shared_libs = allow_windows_shared_libs
322+
self._is_cross = is_cross
323+
self._build_details = build_details
320324

321325
@property
322326
def _has_internal_libs(self) -> bool:
@@ -347,8 +351,8 @@ def tag(self) -> mesonpy._tags.Tag:
347351
# does not contain any extension module (does not
348352
# distribute any file in {platlib}) thus use generic
349353
# implementation and ABI tags.
350-
return mesonpy._tags.Tag('py3', 'none', None)
351-
return mesonpy._tags.Tag(None, self._stable_abi, None)
354+
return mesonpy._tags.Tag('py3', 'none', None, self._build_details)
355+
return mesonpy._tags.Tag(None, self._stable_abi, None, self._build_details)
352356

353357
@property
354358
def name(self) -> str:
@@ -757,6 +761,21 @@ def __init__(
757761
''')
758762
self._meson_native_file.write_text(native_file_data, encoding='utf-8')
759763

764+
# Handle cross compilation
765+
self._is_cross = any(s.startswith('--cross-file') for s in self._meson_args['setup'])
766+
self._build_details = None
767+
if self._is_cross:
768+
# Use build-details.json (PEP 739) to determine
769+
# platform/interpreter/abi tags, if given.
770+
for setup_arg in self._meson_args['setup']:
771+
if setup_arg.startswith('-Dpython.build_config='):
772+
with open(setup_arg.split('-Dpython.build_config=')[1]) as f:
773+
self._build_details = json.load(f)
774+
break
775+
else:
776+
# TODO: warn that interpreter details may be wrong. Get platform from cross file.
777+
pass
778+
760779
# reconfigure if we have a valid Meson build directory. Meson
761780
# uses the presence of the 'meson-private/coredata.dat' file
762781
# in the build directory as indication that the build
@@ -1067,7 +1086,7 @@ def sdist(self, directory: Path) -> pathlib.Path:
10671086
def wheel(self, directory: Path) -> pathlib.Path:
10681087
"""Generates a wheel in the specified directory."""
10691088
self.build()
1070-
builder = _WheelBuilder(self._metadata, self._manifest, self._limited_api, self._allow_windows_shared_libs)
1089+
builder = _WheelBuilder(self._metadata, self._manifest, self._limited_api, self._allow_windows_shared_libs, self._is_cross, self._build_details)
10711090
return builder.build(directory)
10721091

10731092
def editable(self, directory: Path) -> pathlib.Path:

mesonpy/_tags.py

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,15 @@
2929
_32_BIT_INTERPRETER = struct.calcsize('P') == 4
3030

3131

32-
def get_interpreter_tag() -> str:
33-
name = sys.implementation.name
32+
def get_interpreter_tag(build_details: Optional[dict] = None) -> str:
33+
if build_details is None:
34+
name = sys.implementation.name
35+
version = sys.version_info
36+
else:
37+
name = build_details['implementation']['name']
38+
_v = build_details['implementation']['version']
39+
version = (_v['major'], _v['minor'])
3440
name = INTERPRETERS.get(name, name)
35-
version = sys.version_info
3641
return f'{name}{version[0]}{version[1]}'
3742

3843

@@ -53,7 +58,12 @@ def _get_cpython_abi() -> str:
5358
return f'cp{version[0]}{version[1]}{debug}{pymalloc}'
5459

5560

56-
def get_abi_tag() -> str:
61+
def get_abi_tag(build_details: Optional[dict] = None) -> str:
62+
if build_details is not None:
63+
ext_suffix = build_details['abi']['extension_suffix']
64+
else:
65+
ext_suffix = sysconfig.get_config_var('EXT_SUFFIX')
66+
5767
# The best solution to obtain the Python ABI is to parse the
5868
# $SOABI or $EXT_SUFFIX sysconfig variables as defined in PEP-314.
5969

@@ -62,7 +72,7 @@ def get_abi_tag() -> str:
6272
# See https://foss.heptapod.net/pypy/pypy/-/issues/3816 and
6373
# https://github.com/pypa/packaging/pull/607.
6474
try:
65-
empty, abi, ext = str(sysconfig.get_config_var('EXT_SUFFIX')).split('.')
75+
empty, abi, ext = str(ext_suffix).split('.')
6676
except ValueError as exc:
6777
# CPython <= 3.8.7 on Windows does not implement PEP3149 and
6878
# uses '.pyd' as $EXT_SUFFIX, which does not allow to extract
@@ -178,8 +188,8 @@ def _get_ios_platform_tag() -> str:
178188
return f'ios_{version[0]}_{version[1]}_{multiarch}'
179189

180190

181-
def get_platform_tag() -> str:
182-
platform = sysconfig.get_platform()
191+
def get_platform_tag(build_details: Optional[dict] = None) -> str:
192+
platform = build_details['platform'] if build_details is not None else sysconfig.get_platform()
183193
if platform.startswith('macosx'):
184194
return _get_macosx_platform_tag()
185195
if platform.startswith('ios'):
@@ -194,10 +204,10 @@ def get_platform_tag() -> str:
194204

195205

196206
class Tag:
197-
def __init__(self, interpreter: Optional[str] = None, abi: Optional[str] = None, platform: Optional[str] = None):
198-
self.interpreter = interpreter or get_interpreter_tag()
199-
self.abi = abi or get_abi_tag()
200-
self.platform = platform or get_platform_tag()
207+
def __init__(self, interpreter: Optional[str] = None, abi: Optional[str] = None, platform: Optional[str] = None, build_details: Optional[dict] = None):
208+
self.interpreter = interpreter or get_interpreter_tag(build_details)
209+
self.abi = abi or get_abi_tag(build_details)
210+
self.platform = platform or get_platform_tag(build_details)
201211

202212
def __str__(self) -> str:
203213
return f'{self.interpreter}-{self.abi}-{self.platform}'

0 commit comments

Comments
 (0)