Skip to content
Open
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
27 changes: 18 additions & 9 deletions mesonbuild/dependencies/python.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,10 @@
from .framework import ExtraFrameworkDependency
from .pkgconfig import PkgConfigDependency
from ..envconfig import detect_cpu_family
from ..mesonlib import MachineChoice
from ..mesonlib import MachineChoice, path_is_in_root
from ..programs import ExternalProgram
from ..options import OptionKey
from ..scripts import destdir_join

if T.TYPE_CHECKING:
from typing_extensions import Final, TypedDict
Expand Down Expand Up @@ -302,8 +303,9 @@ def find_libpy(self, environment: 'Environment') -> None:
path = self.build_config['libpython'].get('dynamic')
if not path:
raise DependencyException('Python does not provide a dynamic libpython library')
sysroot = environment.properties[self.for_machine].get_sys_root() or ''
path = sysroot + path
sysroot = environment.properties[self.for_machine].get_sys_root()
if sysroot and not path_is_in_root(Path(path), Path(sysroot)):
path = destdir_join(sysroot, path)
if not os.path.isfile(path):
raise DependencyException('Python dynamic library does not exist or is not a file')
self.link_args = [path]
Expand Down Expand Up @@ -356,8 +358,11 @@ def get_windows_link_args(self, limited_api: bool, environment: 'Environment') -
key = 'dynamic-stableabi'
else:
key = 'dynamic'
sysroot = environment.properties[self.for_machine].get_sys_root() or ''
return [sysroot + self.build_config['libpython'][key]]
sysroot = environment.properties[self.for_machine].get_sys_root()
path = self.build_config['libpython'][key]
if sysroot and not path_is_in_root(Path(path), Path(sysroot)):
path = destdir_join(sysroot, path)
return [path]

if self.platform.startswith('win'):
vernum = self.variables.get('py_version_nodot')
Expand Down Expand Up @@ -479,8 +484,9 @@ def __init__(self, name: str, environment: Environment, kwargs: DependencyObject
return

for_machine = kwargs['native']
sysroot = environment.properties[for_machine].get_sys_root() or ''
pkg_libdir = sysroot + pkg_libdir
sysroot = environment.properties[for_machine].get_sys_root()
if sysroot and not path_is_in_root(Path(pkg_libdir), Path(sysroot)):
pkg_libdir = destdir_join(sysroot, pkg_libdir)

mlog.debug(f'Searching for {pkg_libdir!r} via pkgconfig lookup in {pkg_libdir_origin}')
pkgconfig_paths = [pkg_libdir] if pkg_libdir else []
Expand Down Expand Up @@ -541,8 +547,11 @@ def __init__(self, name: str, environment: 'Environment',

# compile args
if self.build_config:
sysroot = environment.properties[self.for_machine].get_sys_root() or ''
inc_paths = mesonlib.OrderedSet([sysroot + self.build_config['c_api']['headers']])
sysroot = environment.properties[self.for_machine].get_sys_root()
path = self.build_config['c_api']['headers']
if sysroot and not path_is_in_root(Path(path), Path(sysroot)):
path = destdir_join(sysroot, path)
inc_paths = mesonlib.OrderedSet([path])
else:
inc_paths = mesonlib.OrderedSet([
self.variables.get('INCLUDEPY'),
Expand Down
69 changes: 43 additions & 26 deletions unittests/allplatformstests.py
Original file line number Diff line number Diff line change
Expand Up @@ -3101,7 +3101,7 @@ def test_python_build_config_extensions(self):
python_build_config = {
'schema_version': '1.0',
'base_interpreter': sys.executable,
'base_prefix': '/usr',
'base_prefix': sys.base_prefix,
'platform': sysconfig.get_platform(),
'language': {
'version': sysconfig.get_python_version(),
Expand Down Expand Up @@ -3168,37 +3168,54 @@ def test_python_build_config_extensions(self):
if with_pkgconfig:
libpc = sysconfig.get_config_var('LIBPC')
if libpc is None:
continue
raise SkipTest('pkg-config subtest skipped because of no LIBPC')
python_build_config['c_api']['pkgconfig_path'] = libpc
# Old Ubuntu versions have incorrect LIBDIR, skip testing non-pkgconfig variant there.
elif not os.path.exists(python_build_config['libpython']['dynamic']):
continue
raise SkipTest('non-pkgconfig subtest skipped because of wrong LIBDIR')

with tempfile.NamedTemporaryFile(mode='w', delete=False, encoding='utf-8') as python_build_config_file:
json.dump(python_build_config, fp=python_build_config_file)
with tempfile.NamedTemporaryFile(mode='w', delete=False, encoding='utf-8') as cross_file:
cross_file.write(
textwrap.dedent(f'''
[binaries]
pkg-config = 'pkg-config'

[built-in options]
python.build_config = '{python_build_config_file.name}'
'''.strip())
)
cross_file.flush()

for extra_args in (
['--python.build-config', python_build_config_file.name],
['--cross-file', cross_file.name],
):
with self.subTest(extra_args=extra_args):
self.init(testdir, extra_args=extra_args)
self.build()
with open(intro_installed_file) as f:
intro_installed = json.load(f)
self.assertEqual(sorted(expected_files), sorted(intro_installed))
self.wipe()
for build_config_via_cross in (False, True):
for sys_root in (None, sys.base_prefix):
with self.subTest(build_config_via_cross=build_config_via_cross, sys_root=sys_root):
# fd.o pkg-config does not handle sys_root correctly
if sys_root is not None and with_pkgconfig and shutil.which('pkgconf') is None:
raise SkipTest('sys_root subtest skipped because of fd.o pkg-config')

with tempfile.NamedTemporaryFile(mode='w', delete=False, encoding='utf-8') as cross_file:
cross_file.write(
textwrap.dedent(f'''
[binaries]
pkg-config = 'pkg-config'
''')
)
if build_config_via_cross:
cross_file.write(
textwrap.dedent(f'''
[built-in options]
python.build_config = '{python_build_config_file.name}'
''')
)
if sys_root is not None:
cross_file.write(
textwrap.dedent(f'''
[properties]
sys_root = '{sys_root}'
''')
)
cross_file.flush()

extra_args = ['--cross-file', cross_file.name]
if not build_config_via_cross:
extra_args += ['--python.build-config', python_build_config_file.name]

self.init(testdir, extra_args=extra_args)
self.build()
with open(intro_installed_file) as f:
intro_installed = json.load(f)
self.assertEqual(sorted(expected_files), sorted(intro_installed))
self.wipe()

def __reconfigure(self):
# Set an older version to force a reconfigure from scratch
Expand Down
Loading