Skip to content

Commit 1778ab6

Browse files
committed
ENH: support shared libraries on Windows when explicitly enabled
Fixes #525.
1 parent 62dd141 commit 1778ab6

File tree

5 files changed

+27
-5
lines changed

5 files changed

+27
-5
lines changed

docs/reference/pyproject-settings.rst

+11
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,17 @@ use them and examples.
3434
``meson-python`` itself. It can be overrridden by the :envvar:`MESON`
3535
environment variable.
3636

37+
.. option:: tool.meson-python.shared-libs-win32
38+
39+
A boolean indicating whether shared libraries should be supported on
40+
Windows. ``meson-python`` installs shared libraries in a dedicated location
41+
and uses RPATH or equivalent mechanisms to have Python modules and native
42+
executables load them form there. Windows does not have an equivalent
43+
mechanism to set the DLL load path. Supporting shared libraries on Windows
44+
requires collaboration from the package. To make sure that package authors
45+
are aware of this requirement, ``meson-python`` raises an error if a
46+
package contains DLLs and this option is not set.
47+
3748
.. option:: tool.meson-python.args.dist
3849

3950
Extra arguments to be passed to the ``meson dist`` command.

mesonpy/__init__.py

+12-2
Original file line numberDiff line numberDiff line change
@@ -311,10 +311,12 @@ def __init__(
311311
metadata: Metadata,
312312
manifest: Dict[str, List[Tuple[pathlib.Path, str]]],
313313
limited_api: bool,
314+
shared_libs_win32: bool,
314315
) -> None:
315316
self._metadata = metadata
316317
self._manifest = manifest
317318
self._limited_api = limited_api
319+
self._shared_libs_win32 = shared_libs_win32
318320

319321
@property
320322
def _has_internal_libs(self) -> bool:
@@ -430,6 +432,9 @@ def _install_path(self, wheel_file: mesonpy._wheelfile.WheelFile, origin: Path,
430432

431433
if self._has_internal_libs:
432434
if _is_native(origin):
435+
if sys.platform == 'win32' and not self._shared_libs_win32:
436+
raise NotImplementedError(f'Bundling libraries in wheel is not supported on {sys.platform}')
437+
433438
# When an executable, libray, or Python extension module is
434439
# dynamically linked to a library built as part of the project,
435440
# Meson adds a library load path to it pointing to the build
@@ -566,6 +571,7 @@ def _string_or_path(value: Any, name: str) -> str:
566571
scheme = _table({
567572
'meson': _string_or_path,
568573
'limited-api': _bool,
574+
'shared-libs-win32': _bool,
569575
'args': _table({
570576
name: _strings for name in _MESON_ARGS_KEYS
571577
}),
@@ -757,6 +763,10 @@ def __init__(
757763
if not value:
758764
self._limited_api = False
759765

766+
# Shared library support on Windows requires collaboration
767+
# from the package, make sure the developpers aknowledge this.
768+
self._shared_libs_win32 = pyproject_config.get('shared-libs-win32', False)
769+
760770
def _run(self, cmd: Sequence[str]) -> None:
761771
"""Invoke a subprocess."""
762772
# Flush the line to ensure that the log line with the executed
@@ -920,13 +930,13 @@ def sdist(self, directory: Path) -> pathlib.Path:
920930
def wheel(self, directory: Path) -> pathlib.Path:
921931
"""Generates a wheel in the specified directory."""
922932
self.build()
923-
builder = _WheelBuilder(self._metadata, self._manifest, self._limited_api)
933+
builder = _WheelBuilder(self._metadata, self._manifest, self._limited_api, self._shared_libs_win32)
924934
return builder.build(directory)
925935

926936
def editable(self, directory: Path) -> pathlib.Path:
927937
"""Generates an editable wheel in the specified directory."""
928938
self.build()
929-
builder = _EditableWheelBuilder(self._metadata, self._manifest, self._limited_api)
939+
builder = _EditableWheelBuilder(self._metadata, self._manifest, self._limited_api, self._shared_libs_win32)
930940
return builder.build(directory, self._source_dir, self._build_dir, self._build_command, self._editable_verbose)
931941

932942

mesonpy/_rpath.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
if sys.platform == 'win32' or sys.platform == 'cygwin':
2020

2121
def fix_rpath(filepath: Path, libs_relative_path: str) -> None:
22-
raise NotImplementedError(f'Bundling libraries in wheel is not supported on {sys.platform}')
22+
pass
2323

2424
elif sys.platform == 'darwin':
2525

tests/test_tags.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ def test_python_host_platform(monkeypatch):
7777
def wheel_builder_test_factory(content, pure=True, limited_api=False):
7878
manifest = defaultdict(list)
7979
manifest.update({key: [(pathlib.Path(x), os.path.join('build', x)) for x in value] for key, value in content.items()})
80-
return mesonpy._WheelBuilder(None, manifest, limited_api)
80+
return mesonpy._WheelBuilder(None, manifest, limited_api, False)
8181

8282

8383
def test_tag_empty_wheel():

tests/test_wheel.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -231,7 +231,8 @@ def test_entrypoints(wheel_full_metadata):
231231

232232
def test_top_level_modules(package_module_types):
233233
with mesonpy._project() as project:
234-
builder = mesonpy._EditableWheelBuilder(project._metadata, project._manifest, project._limited_api)
234+
builder = mesonpy._EditableWheelBuilder(
235+
project._metadata, project._manifest, project._limited_api, project._shared_libs_win32)
235236
assert set(builder._top_level_modules) == {
236237
'file',
237238
'package',

0 commit comments

Comments
 (0)