Skip to content

Commit df2f397

Browse files
committed
ENH: implement support for install_rpath
Revise tests to exercise support when executed with Meson > 1.6
1 parent 7c271bc commit df2f397

4 files changed

Lines changed: 36 additions & 22 deletions

File tree

mesonpy/__init__.py

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,10 @@ def _compile_patterns(patterns: List[str]) -> Callable[[str], bool]:
125125
class _Entry(typing.NamedTuple):
126126
dst: pathlib.Path
127127
src: str
128+
# Meson support only one install_rpath entry per target. Use a
129+
# list to store install RPATH to be able to add append more
130+
# entries when needed.
131+
install_rpath: List[str] = []
128132

129133

130134
def _map_to_wheel(
@@ -183,7 +187,8 @@ def _map_to_wheel(
183187
filedst = dst / relpath
184188
wheel_files[path].append(_Entry(filedst, filesrc))
185189
else:
186-
wheel_files[path].append(_Entry(dst, src))
190+
install_rpath = target.get('install_rpath')
191+
wheel_files[path].append(_Entry(dst, src, [install_rpath] if install_rpath else []))
187192

188193
return wheel_files
189194

@@ -449,13 +454,15 @@ def _stable_abi(self) -> Optional[str]:
449454
return 'abi3.abi3t' if abi3t else 'abi3'
450455
return None
451456

452-
def _install_path(self, wheel_file: mesonpy._wheelfile.WheelFile, origin: Path, destination: pathlib.Path) -> None:
457+
def _install_path(self, wheel_file: mesonpy._wheelfile.WheelFile, origin: Path, destination: pathlib.Path,
458+
install_rpath: List[str]) -> None:
453459
"""Add a file to the wheel."""
454460

455-
if self._has_internal_libs:
456-
if _is_native(origin):
457-
libspath = os.path.relpath(self._libs_dir, destination.parent)
458-
mesonpy._rpath.fix_rpath(origin, libspath)
461+
if self._has_internal_libs and _is_native(origin):
462+
libspath = os.path.relpath(self._libs_dir, destination.parent)
463+
mesonpy._rpath.fix_rpath(origin, install_rpath, libspath)
464+
elif install_rpath:
465+
mesonpy._rpath.fix_rpath(origin, install_rpath, None)
459466

460467
try:
461468
wheel_file.write(origin, destination.as_posix())
@@ -499,7 +506,7 @@ def build(self, directory: Path) -> pathlib.Path:
499506
root = 'purelib' if self._pure else 'platlib'
500507

501508
for path, entries in self._manifest.items():
502-
for dst, src in entries:
509+
for dst, src, install_rpath in entries:
503510
counter.update(src)
504511

505512
if path == root:
@@ -510,7 +517,7 @@ def build(self, directory: Path) -> pathlib.Path:
510517
else:
511518
dst = pathlib.Path(self._data_dir, path, dst)
512519

513-
self._install_path(whl, src, dst)
520+
self._install_path(whl, src, dst, install_rpath)
514521

515522
return wheel_file
516523

mesonpy/_rpath.py

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111

1212

1313
if typing.TYPE_CHECKING:
14-
from typing import List, TypeVar, Union
14+
from typing import List, Optional, TypeVar, Union
1515
Path = Union[str, os.PathLike[str]]
1616
T = TypeVar('T')
1717

@@ -37,7 +37,7 @@ def set_rpath(filepath: Path, old: List[str], rpath: List[str]) -> None:
3737
raise NotImplementedError
3838

3939
@classmethod
40-
def fix_rpath(cls, filepath: Path, libs_relative_path: str) -> None:
40+
def fix_rpath(cls, filepath: Path, install_rpath: List[str], libs_relative_path: Optional[str]) -> None:
4141
old_rpath = cls.get_rpath(filepath)
4242
new_rpath = old_rpath[:]
4343

@@ -51,9 +51,12 @@ def fix_rpath(cls, filepath: Path, libs_relative_path: str) -> None:
5151
# library install location. This heuristic is not perfect: RPATH
5252
# entries relative to ``$ORIGIN`` can exist for other reasons.
5353
# However, this only results in harmless additional RPATH entries.
54-
if any(path.startswith(cls.origin) for path in old_rpath):
54+
if libs_relative_path and any(path.startswith(cls.origin) for path in old_rpath):
5555
new_rpath.append(os.path.join(cls.origin, libs_relative_path))
5656

57+
# Add install_rpath.
58+
new_rpath += install_rpath
59+
5760
new_rpath = unique(new_rpath)
5861
if new_rpath != old_rpath:
5962
cls.set_rpath(filepath, old_rpath, new_rpath)
@@ -62,7 +65,7 @@ def fix_rpath(cls, filepath: Path, libs_relative_path: str) -> None:
6265
class _Windows(RPATH):
6366

6467
@classmethod
65-
def fix_rpath(cls, filepath: Path, libs_relative_path: str) -> None:
68+
def fix_rpath(cls, filepath: Path, install_rpath: List[str], libs_relative_path: str) -> None:
6669
pass
6770

6871

tests/packages/sharedlib-in-package/mypkg/meson.build

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,19 @@
22
#
33
# SPDX-License-Identifier: MIT
44

5+
# install_rpath is not exposed in the Meson introspection data in
6+
# Meson versions prior to 1.6.0 and thus cannot be set by meson-python
7+
# when building the Python wheel. Use link_args to set the RPATH when
8+
# using older Meson.
9+
kwargs = meson.version().version_compare('< 1.6') ? {'link_args': f'-Wl,-rpath,@origin@'} : {'install_rpath': f'@origin@'}
10+
511
py.extension_module(
612
'_example',
713
'_examplemod.c',
814
dependencies: lib_dep,
915
install: true,
1016
subdir: 'mypkg',
11-
# install_rpath is not exposed in the Meson introspection data in Meson
12-
# versions prior to 1.6.0 and thus cannot be set by meson-python when
13-
# building the Python wheel. Use link_args to set the RPATH.
14-
# install_rpath: f'@origin@',
15-
link_args: f'-Wl,-rpath,@origin@',
17+
kwargs: kwargs,
1618
)
1719

1820
py.install_sources(

tests/packages/sharedlib-in-package/src/meson.build

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,18 +23,20 @@ sublib_dep = declare_dependency(
2323
link_with: sublib,
2424
)
2525

26+
# install_rpath is not exposed in the Meson introspection data in
27+
# Meson versions prior to 1.6.0 and thus cannot be set by meson-python
28+
# when building the Python wheel. Use link_args to set the RPATH when
29+
# using older Meson.
30+
kwargs = meson.version().version_compare('< 1.6') ? {'link_args': f'-Wl,-rpath,@origin@/sub'} : {'install_rpath': f'@origin@/sub'}
31+
2632
lib = shared_library(
2733
'lib',
2834
'lib.c',
2935
dependencies: sublib_dep,
3036
c_args: export_dll_args,
3137
install: true,
3238
install_dir: py.get_install_dir() / 'mypkg',
33-
# install_rpath is not exposed in the Meson introspection data in Meson
34-
# versions prior to 1.6.0 and thus cannot be set by meson-python when
35-
# building the Python wheel. Use link_args to set the RPATH.
36-
# install_rpath: f'@origin@/sub',
37-
link_args: f'-Wl,-rpath,@origin@/sub',
39+
kwargs: kwargs,
3840
)
3941

4042
lib_dep = declare_dependency(

0 commit comments

Comments
 (0)