# F2PY and Build Systems

In this section we will cover the various popular build systems and their usage with `f2py`.

Note

As of November 2021

The default build system for `F2PY` has traditionally been through the enhanced `numpy.distutils` module. This module is based on `distutils` which will be removed in `Python 3.12.0` in October 2023; `setuptools` does not have support for Fortran or `F2PY` and it is unclear if it will be supported in the future. Alternative methods are thus increasingly more important.

## Basic Concepts

Building an extension module which includes Python and Fortran consists of:

- Fortran source(s)

- One or more generated files from `f2py`

  - A `C` wrapper file is always created

  - Code with modules require an additional `.f90` wrapper

  - Code with functions generate an additional `.f` wrapper

- `fortranobject.{c,h}`

  - Distributed with `numpy`

  - Can be queried via `python -c "import numpy.f2py; print(numpy.f2py.get_include())"`

- NumPy headers

  - Can be queried via `python -c "import numpy; print(numpy.get_include())"`

- Python libraries and development headers

Broadly speaking there are three cases which arise when considering the outputs of `f2py`:

Fortran 77 programs

  - Input file `blah.f`

  - Generates

    - `blahmodule.c`

    - `blah-f2pywrappers.f`

  When no `COMMON` blocks are present only a `C` wrapper file is generated. Wrappers are also generated to rewrite assumed shape arrays as automatic arrays.

Fortran 90 programs

  - Input file `blah.f90`

  - Generates:

    - `blahmodule.c`

    - `blah-f2pywrappers.f`

    - `blah-f2pywrappers2.f90`

  The `f90` wrapper is used to handle code which is subdivided into modules. The `f` wrapper makes `subroutines` for `functions`. It rewrites assumed shape arrays as automatic arrays.

Signature files

  - Input file `blah.pyf`

  - Generates:

    - `blahmodule.c`

    - `blah-f2pywrappers2.f90` (occasionally)

    - `blah-f2pywrappers.f` (occasionally)

  Signature files `.pyf` do not signal their language standard via the file extension, they may generate the F90 and F77 specific wrappers depending on their contents; which shifts the burden of checking for generated files onto the build system.

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 .

In theory keeping the above requirements in hand, any build system can be adapted to generate `f2py` extension modules. Here we will cover a subset of the more popular systems.

Note

`make` has no place in a modern multi-language setup, and so is not discussed further.

## Build Systems

- Using via `numpy.distutils`
  - Extensions to `distutils`
- Using via `meson`
  - Fibonacci Walkthrough (F77)
  - Salient points
- Using via `cmake`
  - Fibonacci walkthrough (F77)
- Using via `scikit-build`
  - Fibonacci Walkthrough (F77)