Skip to content

Commit

Permalink
ENH: support custom_target() installing a directory
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
dnicolodi authored and rgommers committed Feb 29, 2024
1 parent 2b437bd commit d84cf99
Show file tree
Hide file tree
Showing 7 changed files with 62 additions and 2 deletions.
2 changes: 1 addition & 1 deletion mesonpy/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ def _map_to_wheel(sources: Dict[str, Dict[str, Any]]) -> DefaultDict[str, List[T
f'{this!r} and {that!r}, a "pure: false" argument may be missing in meson.build. '
f'It is recommended to set it in "import(\'python\').find_installation()"')

if key == 'install_subdirs':
if key == 'install_subdirs' or key == 'targets' and os.path.isdir(src):
assert os.path.isdir(src)
exclude_files = {os.path.normpath(x) for x in target.get('exclude_files', [])}
exclude_dirs = {os.path.normpath(x) for x in target.get('exclude_dirs', [])}
Expand Down
2 changes: 1 addition & 1 deletion mesonpy/_editable.py
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,7 @@ def collect(install_plan: Dict[str, Dict[str, Any]]) -> Node:
for src, target in data.items():
path = pathlib.Path(target['destination'])
if path.parts[0] in {'{py_platlib}', '{py_purelib}'}:
if key == 'install_subdirs' and os.path.isdir(src):
if key == 'install_subdirs' or key == 'targets' and os.path.isdir(src):
exclude_files = {os.path.normpath(x) for x in target.get('exclude_files', [])}
exclude_dirs = {os.path.normpath(x) for x in target.get('exclude_dirs', [])}
for entry in walk(src, exclude_files, exclude_dirs):
Expand Down
16 changes: 16 additions & 0 deletions tests/packages/custom-target-dir/codegen.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#!/usr/bin/env python3
#
# SPDX-FileCopyrightText: 2024 The meson-python developers
#
# SPDX-License-Identifier: MIT

import os
import sys


outdir = os.path.join(sys.argv[1], 'generated')
os.makedirs(outdir, exist_ok=True)

for name in 'one.py', 'two.py':
with open(os.path.join(outdir, name), 'w'):
pass
14 changes: 14 additions & 0 deletions tests/packages/custom-target-dir/meson.build
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# SPDX-FileCopyrightText: 2024 The meson-python developers
#
# SPDX-License-Identifier: MIT

project('custom-target-dir', version: '1.0.0')

py = import('python').find_installation()

custom_target(
command: ['codegen.py', '@OUTDIR@'],
output: 'generated',
install: true,
install_dir: py.get_install_dir() / 'package',
)
7 changes: 7 additions & 0 deletions tests/packages/custom-target-dir/pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# SPDX-FileCopyrightText: 2024 The meson-python developers
#
# SPDX-License-Identifier: MIT

[build-system]
build-backend = 'mesonpy'
requires = ['meson-python']
11 changes: 11 additions & 0 deletions tests/test_editable.py
Original file line number Diff line number Diff line change
Expand Up @@ -226,3 +226,14 @@ def test_editable_pkgutils_walk_packages(package_complex, tmp_path):
# remove hooks
del sys.meta_path[0]
del sys.path_hooks[0]


def test_custom_target_install_dir(package_custom_target_dir, tmp_path):
mesonpy.Project(package_custom_target_dir, tmp_path)
finder = _editable.MesonpyMetaFinder({'package'}, os.fspath(tmp_path), ['ninja'])
try:
sys.meta_path.insert(0, finder)
import package.generated.one
import package.generated.two # noqa: F401
finally:
del sys.meta_path[0]
12 changes: 12 additions & 0 deletions tests/test_wheel.py
Original file line number Diff line number Diff line change
Expand Up @@ -350,3 +350,15 @@ def test_encoding(package_encoding, tmp_path):
'encoding-1.0.0.dist-info/WHEEL',
'テスト.py',
}


def test_custom_target_install_dir(package_custom_target_dir, tmp_path):
filename = mesonpy.build_wheel(tmp_path)
artifact = wheel.wheelfile.WheelFile(tmp_path / filename)
assert wheel_contents(artifact) == {
'custom_target_dir-1.0.0.dist-info/METADATA',
'custom_target_dir-1.0.0.dist-info/RECORD',
'custom_target_dir-1.0.0.dist-info/WHEEL',
'package/generated/one.py',
'package/generated/two.py',
}

0 comments on commit d84cf99

Please sign in to comment.