From 696bbb8ed07706fef46e826c3a90eaffddf4589a Mon Sep 17 00:00:00 2001 From: Dylan Baker Date: Thu, 7 Dec 2023 11:51:40 -0800 Subject: [PATCH] python: attempt to make dependency work correctly when cross compiling TODO: write helpful message --- mesonbuild/dependencies/python.py | 41 ++++++++++++++++++++++--------- 1 file changed, 29 insertions(+), 12 deletions(-) diff --git a/mesonbuild/dependencies/python.py b/mesonbuild/dependencies/python.py index 9aea6bda83fb..300abc939b21 100644 --- a/mesonbuild/dependencies/python.py +++ b/mesonbuild/dependencies/python.py @@ -25,7 +25,7 @@ from .framework import ExtraFrameworkDependency from .pkgconfig import PkgConfigDependency from ..environment import detect_cpu_family -from ..programs import ExternalProgram +from ..programs import ExternalProgram, find_external_program if T.TYPE_CHECKING: from typing_extensions import TypedDict @@ -193,8 +193,11 @@ def __init__(self, name: str, environment: 'Environment', class PythonSystemDependency(SystemDependency, _PythonDependencyBase): def __init__(self, name: str, environment: 'Environment', - kwargs: T.Dict[str, T.Any], installation: 'BasicPythonExternalProgram'): + kwargs: T.Dict[str, T.Any], installation: T.Optional[BasicPythonExternalProgram]): SystemDependency.__init__(self, name, environment, kwargs) + if installation is None: + self.is_found = False + return _PythonDependencyBase.__init__(self, installation, kwargs.get('embed', False)) # match pkg-config behavior @@ -358,15 +361,27 @@ def python_factory(env: 'Environment', for_machine: 'MachineChoice', methods = process_method_kw({DependencyMethods.PKGCONFIG, DependencyMethods.SYSTEM}, kwargs) embed = kwargs.get('embed', False) candidates: T.List['DependencyGenerator'] = [] - from_installation = installation is not None - # When not invoked through the python module, default installation. + + # when we're not running from a provided installation, create one using the + # appropriate python from the cross file or native file, or fall back to the + # running python for the host machine. if installation is None: - installation = BasicPythonExternalProgram('python3', mesonlib.python_command) - installation.sanity() - pkg_version = installation.info['variables'].get('LDVERSION') or installation.info['version'] + if not (env.is_cross_build() and env.need_exe_wrapper() and env.exe_wrapper is None): + cmd: T.List[str] = [] + for prog in find_external_program(env, for_machine, 'python3', 'python3', ['python3', 'python'], allow_default_for_cross=False): + if prog.found(): + cmd = T.cast('T.List[str]', prog.command) + break + else: + if not (env.is_cross_build() and for_machine is mesonlib.MachineChoice.HOST): + cmd = mesonlib.python_command + if cmd: + installation = BasicPythonExternalProgram('python3', cmd) + installation.sanity() if DependencyMethods.PKGCONFIG in methods: - if from_installation: + if installation is not None: + pkg_version = installation.info['variables'].get('LDVERSION') or installation.info['version'] pkg_libdir = installation.info['variables'].get('LIBPC') pkg_embed = '-embed' if embed and mesonlib.version_compare(installation.info['version'], '>=3.8') else '' pkg_name = f'python-{pkg_version}{pkg_embed}' @@ -407,10 +422,12 @@ def set_env(name: str, value: str) -> None: if DependencyMethods.EXTRAFRAMEWORK in methods: nkwargs = kwargs.copy() - if mesonlib.version_compare(pkg_version, '>= 3'): - # There is a python in /System/Library/Frameworks, but that's python 2.x, - # Python 3 will always be in /Library - nkwargs['paths'] = ['/Library/Frameworks'] + if installation is not None: + pkg_version = installation.info['variables'].get('LDVERSION') or installation.info['version'] + if mesonlib.version_compare(pkg_version, '>= 3'): + # There is a python in /System/Library/Frameworks, but that's python 2.x, + # Python 3 will always be in /Library + nkwargs['paths'] = ['/Library/Frameworks'] candidates.append(functools.partial(PythonFrameworkDependency, 'Python', env, nkwargs, installation)) return candidates