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 the 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 createdCode with modules require an additional
.f90
wrapperCode 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 aC
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. Thef
wrapper makessubroutines
forfunctions
. 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.