From 3c3c122f1a6398b4a2223e1f750a598b17bf2e42 Mon Sep 17 00:00:00 2001 From: Thomas Robitaille Date: Tue, 3 Mar 2026 11:38:04 +0000 Subject: [PATCH] Switch to meson for building package --- meson.build | 10 +++++ pyproject.toml | 37 ++---------------- reproject/__init__.py | 5 ++- reproject/adaptive/meson.build | 16 ++++++++ reproject/adaptive/tests/meson.build | 13 +++++++ reproject/healpix/meson.build | 9 +++++ reproject/healpix/tests/meson.build | 12 ++++++ reproject/hips/meson.build | 10 +++++ reproject/hips/tests/meson.build | 6 +++ reproject/interpolation/meson.build | 8 ++++ reproject/interpolation/tests/meson.build | 13 +++++++ reproject/meson.build | 17 +++++++++ reproject/mosaicking/meson.build | 10 +++++ reproject/mosaicking/tests/meson.build | 13 +++++++ reproject/spherical_intersect/meson.build | 29 ++++++++++++++ .../spherical_intersect/setup_package.py | 38 ------------------- .../spherical_intersect/tests/meson.build | 7 ++++ reproject/tests/meson.build | 24 ++++++++++++ 18 files changed, 205 insertions(+), 72 deletions(-) create mode 100644 meson.build create mode 100644 reproject/adaptive/meson.build create mode 100644 reproject/adaptive/tests/meson.build create mode 100644 reproject/healpix/meson.build create mode 100644 reproject/healpix/tests/meson.build create mode 100644 reproject/hips/meson.build create mode 100644 reproject/hips/tests/meson.build create mode 100644 reproject/interpolation/meson.build create mode 100644 reproject/interpolation/tests/meson.build create mode 100644 reproject/meson.build create mode 100644 reproject/mosaicking/meson.build create mode 100644 reproject/mosaicking/tests/meson.build create mode 100644 reproject/spherical_intersect/meson.build delete mode 100644 reproject/spherical_intersect/setup_package.py create mode 100644 reproject/spherical_intersect/tests/meson.build create mode 100644 reproject/tests/meson.build diff --git a/meson.build b/meson.build new file mode 100644 index 000000000..9e2b7b6ab --- /dev/null +++ b/meson.build @@ -0,0 +1,10 @@ +project( + 'reproject', + 'c', 'cython', + version: '0.20.0.dev0', + meson_version: '>=1.3.0', +) + +py = import('python').find_installation(pure: false) + +subdir('reproject') diff --git a/pyproject.toml b/pyproject.toml index dde526584..bcc28ffe3 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,3 +1,7 @@ +[build-system] +build-backend = "mesonpy" +requires = ["meson-python", "cython>=3.1", "numpy>=2"] + [project] name = "reproject" authors = [ @@ -55,33 +59,6 @@ dev = [ {include-group = "test"}, ] -[build-system] -requires = ["setuptools", - "setuptools_scm", - "extension-helpers>=1.3,<2", - "numpy>=2", - "cython>=3.1"] -build-backend = 'setuptools.build_meta' - -[tool.setuptools] -zip-safe = false -license-files = ["LICENSE"] -include-package-data = false - -[tool.setuptools.packages] -find = {namespaces = false} - -[tool.setuptools.package-data] -"reproject.healpix.tests" = ["data/*"] -"reproject.adaptive.tests" = ["reference/*"] -"reproject.interpolation.tests" = ["reference/*"] -"reproject.mosaicking.tests" = ["reference/*"] -"reproject.spherical_intersect" = ["overlapArea.h", "reproject_slice_c.h", "mNaN.h"] -"reproject.tests" = ["data/*"] - -[tool.extension-helpers] -use_extension_helpers = "true" - [tool.pytest.ini_options] minversion = "6" log_cli_level = "INFO" @@ -148,9 +125,6 @@ exclude_lines = [ [tool.flake8] max-line-length = "100" -[tool.setuptools_scm] -write_to = "reproject/version.py" - [tool.cibuildwheel] skip = "cp36-* pp* *-musllinux* cp31?t-*" test-skip = "*-manylinux_aarch64" @@ -203,6 +177,3 @@ lint.select = [ [tool.ruff.lint.extend-per-file-ignores] "docs/conf.py" = ["F405"] # Sphinx injects variables into namespace - -[tool.distutils.bdist_wheel] -py-limited-api = "cp311" diff --git a/reproject/__init__.py b/reproject/__init__.py index 53544f90d..6c15d279d 100644 --- a/reproject/__init__.py +++ b/reproject/__init__.py @@ -3,8 +3,11 @@ Astropy affiliated package for image reprojection (resampling). """ +from importlib.metadata import version + from .adaptive import reproject_adaptive # noqa from .healpix import reproject_from_healpix, reproject_to_healpix # noqa from .interpolation import reproject_interp # noqa from .spherical_intersect import reproject_exact # noqa -from .version import __version__ # noqa + +__version__ = version("reproject") diff --git a/reproject/adaptive/meson.build b/reproject/adaptive/meson.build new file mode 100644 index 000000000..d0e809bb6 --- /dev/null +++ b/reproject/adaptive/meson.build @@ -0,0 +1,16 @@ +py.install_sources( + '__init__.py', + 'core.py', + 'high_level.py', + subdir: 'reproject/adaptive', +) + +py.extension_module( + 'deforest', + 'deforest.pyx', + dependencies: dependency('numpy'), + install: true, + subdir: 'reproject/adaptive', +) + +subdir('tests') diff --git a/reproject/adaptive/tests/meson.build b/reproject/adaptive/tests/meson.build new file mode 100644 index 000000000..d5fe478aa --- /dev/null +++ b/reproject/adaptive/tests/meson.build @@ -0,0 +1,13 @@ +py.install_sources( + '__init__.py', + 'test_core.py', + subdir: 'reproject/adaptive/tests', +) + +install_data( + 'reference/test_reproject_adaptive_2d.fits', + 'reference/test_reproject_adaptive_2d_rotated.fits', + 'reference/test_reproject_adaptive_roundtrip.fits', + 'reference/test_reproject_adaptive_uncentered_jacobian.fits', + install_dir: py.get_install_dir() / 'reproject/adaptive/tests/reference', +) diff --git a/reproject/healpix/meson.build b/reproject/healpix/meson.build new file mode 100644 index 000000000..90b4ea746 --- /dev/null +++ b/reproject/healpix/meson.build @@ -0,0 +1,9 @@ +py.install_sources( + '__init__.py', + 'core.py', + 'high_level.py', + 'utils.py', + subdir: 'reproject/healpix', +) + +subdir('tests') diff --git a/reproject/healpix/tests/meson.build b/reproject/healpix/tests/meson.build new file mode 100644 index 000000000..585b9bc46 --- /dev/null +++ b/reproject/healpix/tests/meson.build @@ -0,0 +1,12 @@ +py.install_sources( + '__init__.py', + 'test_healpix.py', + 'test_utils.py', + subdir: 'reproject/healpix/tests', +) + +install_data( + 'data/bayestar.fits.gz', + 'data/reference_result.fits', + install_dir: py.get_install_dir() / 'reproject/healpix/tests/data', +) diff --git a/reproject/hips/meson.build b/reproject/hips/meson.build new file mode 100644 index 000000000..dc2018b00 --- /dev/null +++ b/reproject/hips/meson.build @@ -0,0 +1,10 @@ +py.install_sources( + '__init__.py', + '_dask_array.py', + '_trim_utils.py', + 'high_level.py', + 'utils.py', + subdir: 'reproject/hips', +) + +subdir('tests') diff --git a/reproject/hips/tests/meson.build b/reproject/hips/tests/meson.build new file mode 100644 index 000000000..20843e4e5 --- /dev/null +++ b/reproject/hips/tests/meson.build @@ -0,0 +1,6 @@ +py.install_sources( + '__init__.py', + 'test_dask_array.py', + 'test_high_level.py', + subdir: 'reproject/hips/tests', +) diff --git a/reproject/interpolation/meson.build b/reproject/interpolation/meson.build new file mode 100644 index 000000000..c7f6a3bda --- /dev/null +++ b/reproject/interpolation/meson.build @@ -0,0 +1,8 @@ +py.install_sources( + '__init__.py', + 'core.py', + 'high_level.py', + subdir: 'reproject/interpolation', +) + +subdir('tests') diff --git a/reproject/interpolation/tests/meson.build b/reproject/interpolation/tests/meson.build new file mode 100644 index 000000000..5de5f8fb8 --- /dev/null +++ b/reproject/interpolation/tests/meson.build @@ -0,0 +1,13 @@ +py.install_sources( + '__init__.py', + 'test_core.py', + subdir: 'reproject/interpolation/tests', +) + +install_data( + 'reference/test_reproject_celestial_2d_gal2equ.fits', + 'reference/test_reproject_celestial_3d_equ2gal.fits', + 'reference/test_reproject_roundtrip.fits', + 'reference/test_small_cutout.fits', + install_dir: py.get_install_dir() / 'reproject/interpolation/tests/reference', +) diff --git a/reproject/meson.build b/reproject/meson.build new file mode 100644 index 000000000..06cbfb6c5 --- /dev/null +++ b/reproject/meson.build @@ -0,0 +1,17 @@ +py.install_sources( + '__init__.py', + 'array_utils.py', + 'common.py', + 'conftest.py', + 'utils.py', + 'wcs_utils.py', + subdir: 'reproject', +) + +subdir('adaptive') +subdir('healpix') +subdir('hips') +subdir('interpolation') +subdir('mosaicking') +subdir('spherical_intersect') +subdir('tests') diff --git a/reproject/mosaicking/meson.build b/reproject/mosaicking/meson.build new file mode 100644 index 000000000..54ef4e817 --- /dev/null +++ b/reproject/mosaicking/meson.build @@ -0,0 +1,10 @@ +py.install_sources( + '__init__.py', + 'background.py', + 'coadd.py', + 'subset_array.py', + 'wcs_helpers.py', + subdir: 'reproject/mosaicking', +) + +subdir('tests') diff --git a/reproject/mosaicking/tests/meson.build b/reproject/mosaicking/tests/meson.build new file mode 100644 index 000000000..ded2a0889 --- /dev/null +++ b/reproject/mosaicking/tests/meson.build @@ -0,0 +1,13 @@ +py.install_sources( + '__init__.py', + 'test_background.py', + 'test_coadd.py', + 'test_subset_array.py', + 'test_wcs_helpers.py', + subdir: 'reproject/mosaicking/tests', +) + +install_data( + 'reference/test_coadd_solar_map.fits', + install_dir: py.get_install_dir() / 'reproject/mosaicking/tests/reference', +) diff --git a/reproject/spherical_intersect/meson.build b/reproject/spherical_intersect/meson.build new file mode 100644 index 000000000..f2b0eb692 --- /dev/null +++ b/reproject/spherical_intersect/meson.build @@ -0,0 +1,29 @@ +py.install_sources( + '__init__.py', + 'core.py', + 'high_level.py', + 'overlap.py', + subdir: 'reproject/spherical_intersect', +) + +# Install header files needed at runtime for potential rebuilds +py.install_sources( + 'mNaN.h', + 'overlapArea.h', + 'reproject_slice_c.h', + subdir: 'reproject/spherical_intersect', +) + +py.extension_module( + '_overlap', + '_overlap.pyx', + 'overlapArea.c', + 'reproject_slice_c.c', + dependencies: dependency('numpy'), + include_directories: include_directories('.'), + c_args: ['-O2'], + install: true, + subdir: 'reproject/spherical_intersect', +) + +subdir('tests') diff --git a/reproject/spherical_intersect/setup_package.py b/reproject/spherical_intersect/setup_package.py deleted file mode 100644 index 0fa4d6b53..000000000 --- a/reproject/spherical_intersect/setup_package.py +++ /dev/null @@ -1,38 +0,0 @@ -import os - -import numpy as np -from setuptools import Extension - -REPROJECT_ROOT = os.path.relpath(os.path.dirname(__file__)) - - -def get_extensions(): - libraries = [] - - sources = [] - sources.append(os.path.join(REPROJECT_ROOT, "_overlap.pyx")) - sources.append(os.path.join(REPROJECT_ROOT, "overlapArea.c")) - sources.append(os.path.join(REPROJECT_ROOT, "reproject_slice_c.c")) - - include_dirs = [np.get_include()] - include_dirs.append(REPROJECT_ROOT) - - # Note that to set the DEBUG variable in the overlapArea.c code, which - # results in debugging information being printed out, you can set - # DEBUG_OVERLAP_AREA=1 at build-time. - if int(os.environ.get("DEBUG_OVERLAP_AREA", 0)): - define_macros = [("DEBUG_OVERLAP_AREA", 1)] - else: - define_macros = None - - extension = Extension( - name="reproject.spherical_intersect._overlap", - sources=sources, - include_dirs=include_dirs, - libraries=libraries, - language="c", - extra_compile_args=["-O2"], - define_macros=define_macros, - ) - - return [extension] diff --git a/reproject/spherical_intersect/tests/meson.build b/reproject/spherical_intersect/tests/meson.build new file mode 100644 index 000000000..7540aca9d --- /dev/null +++ b/reproject/spherical_intersect/tests/meson.build @@ -0,0 +1,7 @@ +py.install_sources( + '__init__.py', + 'test_high_level.py', + 'test_overlap.py', + 'test_reproject.py', + subdir: 'reproject/spherical_intersect/tests', +) diff --git a/reproject/tests/meson.build b/reproject/tests/meson.build new file mode 100644 index 000000000..de063c967 --- /dev/null +++ b/reproject/tests/meson.build @@ -0,0 +1,24 @@ +py.install_sources( + '__init__.py', + 'helpers.py', + 'test_array_utils.py', + 'test_high_level.py', + 'test_utils.py', + subdir: 'reproject/tests', +) + +install_data( + 'data/aia_171_level1.asdf', + 'data/aia_171_level1.fits', + 'data/cube.hdr', + 'data/equatorial_3d.fits', + 'data/galactic_2d.fits', + 'data/gc_eq.hdr', + 'data/gc_ga.hdr', + 'data/generate_asdf.py', + 'data/image_with_distortion_map.fits', + 'data/mwpan2_RGB_3600.hdr', + 'data/secchi_l0_a.fits', + 'data/secchi_l0_b.fits', + install_dir: py.get_install_dir() / 'reproject/tests/data', +)