summaryrefslogtreecommitdiff
path: root/numpy/_build_utils
diff options
context:
space:
mode:
authorCharles Harris <charlesr.harris@gmail.com>2023-05-13 11:02:49 -0600
committerGitHub <noreply@github.com>2023-05-13 11:02:49 -0600
commit5187067d7ad176ee3614beab2b99a524dd719aa8 (patch)
tree907997d0c294f550193322aaa73237c1a7bcfaa6 /numpy/_build_utils
parentb786189222ac5bf2f4efbb04399261f7f760bc18 (diff)
parent81caed6e3c34c4bf4b22b4f6167e816ba2a3f73c (diff)
downloadnumpy-5187067d7ad176ee3614beab2b99a524dd719aa8.tar.gz
Merge branch 'main' into deprecate-find-common-type
Diffstat (limited to 'numpy/_build_utils')
-rw-r--r--numpy/_build_utils/__init__.py22
-rw-r--r--numpy/_build_utils/gcc_build_bitness.py21
-rw-r--r--numpy/_build_utils/process_src_template.py67
-rw-r--r--numpy/_build_utils/setup.py12
-rwxr-xr-xnumpy/_build_utils/tempita.py62
5 files changed, 184 insertions, 0 deletions
diff --git a/numpy/_build_utils/__init__.py b/numpy/_build_utils/__init__.py
new file mode 100644
index 000000000..ac4908957
--- /dev/null
+++ b/numpy/_build_utils/__init__.py
@@ -0,0 +1,22 @@
+# Don't use the deprecated NumPy C API. Define this to a fixed version
+# instead of NPY_API_VERSION in order not to break compilation for
+# released SciPy versions when NumPy introduces a new deprecation. Use
+# in setup.py::
+#
+# config.add_extension('_name', sources=['source_fname'], **numpy_nodepr_api)
+#
+numpy_nodepr_api = dict(
+ define_macros=[("NPY_NO_DEPRECATED_API", "NPY_1_9_API_VERSION")]
+)
+
+
+def import_file(folder, module_name):
+ """Import a file directly, avoiding importing scipy"""
+ import importlib
+ import pathlib
+
+ fname = pathlib.Path(folder) / f'{module_name}.py'
+ spec = importlib.util.spec_from_file_location(module_name, str(fname))
+ module = importlib.util.module_from_spec(spec)
+ spec.loader.exec_module(module)
+ return module
diff --git a/numpy/_build_utils/gcc_build_bitness.py b/numpy/_build_utils/gcc_build_bitness.py
new file mode 100644
index 000000000..fcad237e9
--- /dev/null
+++ b/numpy/_build_utils/gcc_build_bitness.py
@@ -0,0 +1,21 @@
+#!python
+""" Detect bitness (32 or 64) of Mingw-w64 gcc build target on Windows.
+"""
+
+import re
+from subprocess import run, PIPE
+
+
+def main():
+ res = run(['gcc', '-v'], check=True, text=True, capture_output=True)
+ target = re.search(r'^Target: (.*)$', res.stderr, flags=re.M).groups()[0]
+ if target.startswith('i686'):
+ print('32')
+ elif target.startswith('x86_64'):
+ print('64')
+ else:
+ raise RuntimeError('Could not detect Mingw-w64 bitness')
+
+
+if __name__ == "__main__":
+ main()
diff --git a/numpy/_build_utils/process_src_template.py b/numpy/_build_utils/process_src_template.py
new file mode 100644
index 000000000..4a0915e25
--- /dev/null
+++ b/numpy/_build_utils/process_src_template.py
@@ -0,0 +1,67 @@
+#!/usr/bin/env python3
+import sys
+import os
+import argparse
+import importlib.util
+
+
+def get_processor():
+ # Convoluted because we can't import from numpy.distutils
+ # (numpy is not yet built)
+ conv_template_path = os.path.join(
+ os.path.dirname(__file__),
+ '..', 'distutils', 'conv_template.py'
+ )
+ spec = importlib.util.spec_from_file_location(
+ 'conv_template', conv_template_path
+ )
+ mod = importlib.util.module_from_spec(spec)
+ spec.loader.exec_module(mod)
+ return mod.process_file
+
+
+def process_and_write_file(fromfile, outfile):
+ """Process tempita templated file and write out the result.
+
+ The template file is expected to end in `.src`
+ (e.g., `.c.src` or `.h.src`).
+ Processing `npy_somefile.c.src` generates `npy_somefile.c`.
+
+ """
+ process_file = get_processor()
+ content = process_file(fromfile)
+ with open(outfile, 'w') as f:
+ f.write(content)
+
+
+def main():
+ parser = argparse.ArgumentParser()
+ parser.add_argument(
+ "infile",
+ type=str,
+ help="Path to the input file"
+ )
+ parser.add_argument(
+ "-o",
+ "--outfile",
+ type=str,
+ help="Path to the output file"
+ )
+ parser.add_argument(
+ "-i",
+ "--ignore",
+ type=str,
+ help="An ignored input - may be useful to add a "
+ "dependency between custom targets",
+ )
+ args = parser.parse_args()
+
+ if not args.infile.endswith('.src'):
+ raise ValueError(f"Unexpected extension: {args.infile}")
+
+ outfile_abs = os.path.join(os.getcwd(), args.outfile)
+ process_and_write_file(args.infile, outfile_abs)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/numpy/_build_utils/setup.py b/numpy/_build_utils/setup.py
new file mode 100644
index 000000000..73a8f2fff
--- /dev/null
+++ b/numpy/_build_utils/setup.py
@@ -0,0 +1,12 @@
+def configuration(parent_package='', top_path=None):
+ from numpy.distutils.misc_util import Configuration
+
+ config = Configuration('_build_utils', parent_package, top_path)
+ config.add_data_dir('tests')
+ return config
+
+
+if __name__ == '__main__':
+ from numpy.distutils.core import setup
+
+ setup(**configuration(top_path='').todict())
diff --git a/numpy/_build_utils/tempita.py b/numpy/_build_utils/tempita.py
new file mode 100755
index 000000000..3bcc789c5
--- /dev/null
+++ b/numpy/_build_utils/tempita.py
@@ -0,0 +1,62 @@
+#!/usr/bin/env python3
+import sys
+import os
+import argparse
+
+from Cython import Tempita as tempita
+
+# XXX: If this import ever fails (does it really?), vendor either
+# cython.tempita or numpy/npy_tempita.
+
+
+def process_tempita(fromfile, outfile=None):
+ """Process tempita templated file and write out the result.
+
+ The template file is expected to end in `.c.in` or `.pyx.in`:
+ E.g. processing `template.c.in` generates `template.c`.
+
+ """
+ if outfile is None:
+ # We're dealing with a distutils build here, write in-place
+ outfile = os.path.splitext(fromfile)[0]
+
+ from_filename = tempita.Template.from_filename
+ template = from_filename(fromfile, encoding=sys.getdefaultencoding())
+
+ content = template.substitute()
+
+ with open(outfile, 'w') as f:
+ f.write(content)
+
+
+def main():
+ parser = argparse.ArgumentParser()
+ parser.add_argument(
+ "infile",
+ type=str,
+ help="Path to the input file"
+ )
+ parser.add_argument(
+ "-o",
+ "--outfile",
+ type=str,
+ help="Path to the output file"
+ )
+ parser.add_argument(
+ "-i",
+ "--ignore",
+ type=str,
+ help="An ignored input - may be useful to add a "
+ "dependency between custom targets",
+ )
+ args = parser.parse_args()
+
+ if not args.infile.endswith('.in'):
+ raise ValueError(f"Unexpected extension: {args.infile}")
+
+ outfile_abs = os.path.join(os.getcwd(), args.outfile)
+ process_tempita(args.infile, outfile_abs)
+
+
+if __name__ == "__main__":
+ main()