File: meson.rst

package info (click to toggle)
numpy 1%3A2.2.4%2Bds-1
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 83,420 kB
  • sloc: python: 248,499; asm: 232,365; ansic: 216,874; cpp: 135,657; f90: 1,540; sh: 938; fortran: 558; makefile: 409; sed: 139; xml: 109; java: 92; perl: 79; cs: 54; javascript: 53; objc: 29; lex: 13; yacc: 9
file content (121 lines) | stat: -rw-r--r-- 3,843 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
.. _f2py-meson:

===================
Using via ``meson``
===================

.. note::

   Much of this document is now obsoleted, one can run ``f2py`` with
   ``--build-dir`` to get a skeleton ``meson`` project with basic dependencies
   setup.

.. versionchanged:: 1.26.x

   The default build system for ``f2py`` is now ``meson``, see
   :ref:`distutils-status-migration` for some more details..

The key advantage gained by leveraging ``meson`` over the techniques described
in :ref:`f2py-distutils` is that this feeds into existing systems and larger
projects with ease. ``meson`` has a rather pythonic syntax which makes it more
comfortable and amenable to extension for ``python`` users.

Fibonacci walkthrough (F77)
===========================

We will need the generated ``C`` wrapper before we can use a general purpose
build system like ``meson``. We will acquire this by:

.. code-block:: bash

    python -m numpy.f2py fib1.f -m fib2

Now, consider the following ``meson.build`` file for the ``fib`` and ``scalar``
examples from :ref:`f2py-getting-started` section:

.. literalinclude:: ../code/meson.build

At this point the build will complete, but the import will fail:

.. code-block:: bash

   meson setup builddir
   meson compile -C builddir
   cd builddir
   python -c 'import fib2'
   Traceback (most recent call last):
   File "<string>", line 1, in <module>
   ImportError: fib2.cpython-39-x86_64-linux-gnu.so: undefined symbol: FIB_
   # Check this isn't a false positive
   nm -A fib2.cpython-39-x86_64-linux-gnu.so | grep FIB_
   fib2.cpython-39-x86_64-linux-gnu.so: U FIB_

Recall that the original example, as reproduced below, was in SCREAMCASE:

.. literalinclude:: ./../code/fib1.f
   :language: fortran

With the standard approach, the subroutine exposed to ``python`` is ``fib`` and
not ``FIB``. This means we have a few options. One approach (where possible) is
to lowercase the original Fortran file with say:

.. code-block:: bash

   tr "[:upper:]" "[:lower:]" < fib1.f > fib1.f
   python -m numpy.f2py fib1.f -m fib2
   meson --wipe builddir
   meson compile -C builddir
   cd builddir
   python -c 'import fib2'

However this requires the ability to modify the source which is not always
possible. The easiest way to solve this is to let ``f2py`` deal with it:

.. code-block:: bash

   python -m numpy.f2py fib1.f -m fib2 --lower
   meson --wipe builddir
   meson compile -C builddir
   cd builddir
   python -c 'import fib2'


Automating wrapper generation
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

A major pain point in the workflow defined above, is the manual tracking of
inputs. Although it would require more effort to figure out the actual outputs
for reasons discussed in :ref:`f2py-bldsys`.

.. note::

   From NumPy ``1.22.4`` onwards, ``f2py`` will deterministically generate
   wrapper files based on the input file Fortran standard (F77 or greater).
   ``--skip-empty-wrappers`` can be passed to ``f2py`` to restore the previous
   behaviour of only generating wrappers when needed by the input .

However, we can augment our workflow in a straightforward to take into account
files for which the outputs are known when the build system is set up.

.. literalinclude:: ../code/meson_upd.build

This can be compiled and run as before.

.. code-block:: bash

    rm -rf builddir
    meson setup builddir
    meson compile -C builddir
    cd builddir
    python -c "import numpy as np; import fibby; a = np.zeros(9); fibby.fib(a); print (a)"
    # [ 0.  1.  1.  2.  3.  5.  8. 13. 21.]

Salient points
===============

It is worth keeping in mind the following:

* It is not possible to use SCREAMCASE in this context, so either the contents
  of the ``.f`` file or the generated wrapper ``.c`` needs to be lowered to
  regular letters; which can be facilitated by the ``--lower`` option of
  ``F2PY``