math/py-numpy1: backport configtool/pkg-config file from numpy 2

Traditionally the way to query for the numpy C API has been through
distutils/setuptools, but the use of setuptools beyond a PEP-517
build backend is increasingly discouraged. numpy 2 introduced
numpy-config and a pkg-config file to allow consumer build systems
to better support the use of numpy as a dependency.

Based on: https://github.com/numpy/numpy/commit/2634f803313f349170c09606d3cc619accd72247

Reported by: fluffy
PR: 281470
This commit is contained in:
Charlie Li
2026-04-03 21:47:26 -04:00
parent 4cb2a22ffa
commit 28081ef832
8 changed files with 189 additions and 0 deletions
+1
View File
@@ -1,5 +1,6 @@
PORTNAME= numpy
DISTVERSION= 1.26.4
PORTREVISION= 1
CATEGORIES= math python
MASTER_SITES= PYPI \
https://numpy.org/doc/${DISTVERSION:R}/:doc
@@ -0,0 +1,42 @@
--- numpy/_configtool.py.orig 2026-04-04 01:24:53 UTC
+++ numpy/_configtool.py
@@ -0,0 +1,39 @@
+import argparse
+from pathlib import Path
+import sys
+
+from .version import __version__
+from .lib.utils import get_include
+
+
+def main() -> None:
+ parser = argparse.ArgumentParser()
+ parser.add_argument(
+ "--version",
+ action="version",
+ version=__version__,
+ help="Print the version and exit.",
+ )
+ parser.add_argument(
+ "--cflags",
+ action="store_true",
+ help="Compile flag needed when using the NumPy headers.",
+ )
+ parser.add_argument(
+ "--pkgconfigdir",
+ action="store_true",
+ help=("Print the pkgconfig directory in which `numpy.pc` is stored "
+ "(useful for setting $PKG_CONFIG_PATH)."),
+ )
+ args = parser.parse_args()
+ if not sys.argv[1:]:
+ parser.print_help()
+ if args.cflags:
+ print("-I" + get_include())
+ if args.pkgconfigdir:
+ _path = Path(get_include()) / '..' / 'lib' / 'pkgconfig'
+ print(_path.resolve())
+
+
+if __name__ == "__main__":
+ main()
@@ -0,0 +1,26 @@
--- numpy/core/meson.build.orig 2024-02-05 21:17:48 UTC
+++ numpy/core/meson.build
@@ -621,6 +621,23 @@ src_ufunc_api = custom_target('__ufunc_api',
install_dir: np_dir / 'core/include/numpy'
)
+# Write out pkg-config file
+# -------------------------
+
+# Note: we can't use Meson's built-in pkgconfig module, because we have to
+# install numpy.pc within site-packages rather than in its normal location.
+cdata_numpy_pc = configuration_data()
+cdata_numpy_pc.set('version', meson.project_version())
+
+# Note: keep install path in sync with numpy/_configtool.py
+_numpy_pc = configure_file(
+ input: 'numpy.pc.in',
+ output: 'numpy.pc',
+ configuration: cdata_numpy_pc,
+ install: true,
+ install_dir: np_dir / 'core/lib/pkgconfig',
+ install_tag: 'devel'
+)
# Set common build flags for C and C++ code
# -----------------------------------------
@@ -0,0 +1,10 @@
--- numpy/core/numpy.pc.in.orig 2026-04-04 00:13:21 UTC
+++ numpy/core/numpy.pc.in
@@ -0,0 +1,7 @@
+prefix=${pcfiledir}/../..
+includedir=${prefix}/include
+
+Name: numpy
+Description: NumPy is the fundamental package for scientific computing with Python.
+Version: @version@
+Cflags: -I${includedir}
@@ -0,0 +1,35 @@
--- numpy/lib/utils.py.orig 2024-02-05 21:17:48 UTC
+++ numpy/lib/utils.py
@@ -76,18 +76,29 @@ def get_include():
"""
Return the directory that contains the NumPy \\*.h header files.
- Extension modules that need to compile against NumPy should use this
+ Extension modules that need to compile against NumPy may need to use this
function to locate the appropriate include directory.
Notes
-----
- When using ``distutils``, for example in ``setup.py``::
+ When using ``setuptools``, for example in ``setup.py``::
import numpy as np
...
Extension('extension_name', ...
- include_dirs=[np.get_include()])
+ include_dirs=[np.get_include()])
...
+
+ Note that a CLI tool ``numpy-config`` was introduced in NumPy 2.0, using
+ that is likely preferred for build systems other than ``setuptools``::
+
+ $ numpy-config --cflags
+ -I/path/to/site-packages/numpy/_core/include
+
+ # Or rely on pkg-config:
+ $ export PKG_CONFIG_PATH=$(numpy-config --pkgconfigdir)
+ $ pkg-config --cflags
+ -I/path/to/site-packages/numpy/_core/include
"""
import numpy
@@ -0,0 +1,10 @@
--- numpy/meson.build.orig 2024-02-05 21:17:48 UTC
+++ numpy/meson.build
@@ -215,6 +215,7 @@ python_sources = [
'__init__.pxd',
'__init__.py',
'__init__.pyi',
+ '_configtool.py',
'_distributor_init.py',
'_globals.py',
'_pytesttester.py',
@@ -0,0 +1,44 @@
--- numpy/tests/test_configtool.py.orig 2026-04-04 00:20:07 UTC
+++ numpy/tests/test_configtool.py
@@ -0,0 +1,41 @@
+import os
+import subprocess
+import sysconfig
+
+import pytest
+import numpy as np
+
+
+is_editable = not bool(np.__path__)
+numpy_in_sitepackages = sysconfig.get_path('platlib') in np.__file__
+# We only expect to have a `numpy-config` available if NumPy was installed via
+# a build frontend (and not `spin` for example)
+if not (numpy_in_sitepackages or is_editable):
+ pytest.skip("`numpy-config` not expected to be installed",
+ allow_module_level=True)
+
+
+def check_numpyconfig(arg):
+ p = subprocess.run(['numpy-config', arg], capture_output=True, text=True)
+ p.check_returncode()
+ return p.stdout.strip()
+
+
+def test_configtool_version():
+ stdout = check_numpyconfig('--version')
+ assert stdout == np.__version__
+
+
+def test_configtool_cflags():
+ stdout = check_numpyconfig('--cflags')
+ assert stdout.endswith(os.path.join('numpy', 'core', 'include'))
+
+
+def test_configtool_pkgconfigdir():
+ stdout = check_numpyconfig('--pkgconfigdir')
+ assert stdout.endswith(os.path.join('numpy', 'core', 'lib', 'pkgconfig'))
+
+ if not is_editable:
+ # Also check that the .pc file actually exists (unless we're using an
+ # editable install, then it'll be hiding in the build dir)
+ assert os.path.exists(os.path.join(stdout, 'numpy.pc'))
+21
View File
@@ -0,0 +1,21 @@
--- pyproject.toml.orig 2024-02-05 21:17:48 UTC
+++ pyproject.toml
@@ -1,8 +1,8 @@ requires = [
[build-system]
build-backend = "mesonpy"
requires = [
- "Cython>=0.29.34,<3.1",
- "meson-python>=0.15.0,<0.16.0",
+ "Cython>=0.29.34",
+ "meson-python>=0.15.0",
]
[project]
@@ -43,6 +43,7 @@ f2py = 'numpy.f2py.f2py2e:main'
[project.scripts]
f2py = 'numpy.f2py.f2py2e:main'
+numpy-config = 'numpy._configtool:main'
[project.entry-points.array_api]
numpy = 'numpy.array_api'