Skip to content

Commit d84cf99

Browse files
dnicolodirgommers
authored andcommitted
ENH: support custom_target() installing a directory
Meson support custom_target() whose output is not a file but a directory. Support these in meson-python mapping of installation paths to wheel locations.
1 parent 2b437bd commit d84cf99

File tree

7 files changed

+62
-2
lines changed

7 files changed

+62
-2
lines changed

mesonpy/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ def _map_to_wheel(sources: Dict[str, Dict[str, Any]]) -> DefaultDict[str, List[T
119119
f'{this!r} and {that!r}, a "pure: false" argument may be missing in meson.build. '
120120
f'It is recommended to set it in "import(\'python\').find_installation()"')
121121

122-
if key == 'install_subdirs':
122+
if key == 'install_subdirs' or key == 'targets' and os.path.isdir(src):
123123
assert os.path.isdir(src)
124124
exclude_files = {os.path.normpath(x) for x in target.get('exclude_files', [])}
125125
exclude_dirs = {os.path.normpath(x) for x in target.get('exclude_dirs', [])}

mesonpy/_editable.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -245,7 +245,7 @@ def collect(install_plan: Dict[str, Dict[str, Any]]) -> Node:
245245
for src, target in data.items():
246246
path = pathlib.Path(target['destination'])
247247
if path.parts[0] in {'{py_platlib}', '{py_purelib}'}:
248-
if key == 'install_subdirs' and os.path.isdir(src):
248+
if key == 'install_subdirs' or key == 'targets' and os.path.isdir(src):
249249
exclude_files = {os.path.normpath(x) for x in target.get('exclude_files', [])}
250250
exclude_dirs = {os.path.normpath(x) for x in target.get('exclude_dirs', [])}
251251
for entry in walk(src, exclude_files, exclude_dirs):
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
#!/usr/bin/env python3
2+
#
3+
# SPDX-FileCopyrightText: 2024 The meson-python developers
4+
#
5+
# SPDX-License-Identifier: MIT
6+
7+
import os
8+
import sys
9+
10+
11+
outdir = os.path.join(sys.argv[1], 'generated')
12+
os.makedirs(outdir, exist_ok=True)
13+
14+
for name in 'one.py', 'two.py':
15+
with open(os.path.join(outdir, name), 'w'):
16+
pass
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# SPDX-FileCopyrightText: 2024 The meson-python developers
2+
#
3+
# SPDX-License-Identifier: MIT
4+
5+
project('custom-target-dir', version: '1.0.0')
6+
7+
py = import('python').find_installation()
8+
9+
custom_target(
10+
command: ['codegen.py', '@OUTDIR@'],
11+
output: 'generated',
12+
install: true,
13+
install_dir: py.get_install_dir() / 'package',
14+
)
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# SPDX-FileCopyrightText: 2024 The meson-python developers
2+
#
3+
# SPDX-License-Identifier: MIT
4+
5+
[build-system]
6+
build-backend = 'mesonpy'
7+
requires = ['meson-python']

tests/test_editable.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -226,3 +226,14 @@ def test_editable_pkgutils_walk_packages(package_complex, tmp_path):
226226
# remove hooks
227227
del sys.meta_path[0]
228228
del sys.path_hooks[0]
229+
230+
231+
def test_custom_target_install_dir(package_custom_target_dir, tmp_path):
232+
mesonpy.Project(package_custom_target_dir, tmp_path)
233+
finder = _editable.MesonpyMetaFinder({'package'}, os.fspath(tmp_path), ['ninja'])
234+
try:
235+
sys.meta_path.insert(0, finder)
236+
import package.generated.one
237+
import package.generated.two # noqa: F401
238+
finally:
239+
del sys.meta_path[0]

tests/test_wheel.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -350,3 +350,15 @@ def test_encoding(package_encoding, tmp_path):
350350
'encoding-1.0.0.dist-info/WHEEL',
351351
'テスト.py',
352352
}
353+
354+
355+
def test_custom_target_install_dir(package_custom_target_dir, tmp_path):
356+
filename = mesonpy.build_wheel(tmp_path)
357+
artifact = wheel.wheelfile.WheelFile(tmp_path / filename)
358+
assert wheel_contents(artifact) == {
359+
'custom_target_dir-1.0.0.dist-info/METADATA',
360+
'custom_target_dir-1.0.0.dist-info/RECORD',
361+
'custom_target_dir-1.0.0.dist-info/WHEEL',
362+
'package/generated/one.py',
363+
'package/generated/two.py',
364+
}

0 commit comments

Comments
 (0)