1 Migrating to meson#

As per the timeline laid out in Status of numpy.distutils and migration advice, distutils has ceased to be the default build backend for f2py. This page collects common workflows in both formats.


This is a **living** document, pull requests are very welcome!

1.1 Baseline#

We will start out with a slightly modern variation of the classic Fibonnaci series generator.

! fib.f90
subroutine fib(a, n)
  use iso_c_binding
   integer(c_int), intent(in) :: n
   integer(c_int), intent(out) :: a(n)
   do i = 1, n
      if (i .eq. 1) then
         a(i) = 0.0d0
      elseif (i .eq. 2) then
         a(i) = 1.0d0
         a(i) = a(i - 1) + a(i - 2)
      end if
   end do

This will not win any awards, but can be a reasonable starting point.

1.2 Compilation options#

1.2.1 Basic Usage#

This is unchanged:

python -m numpy.f2py -c fib.f90 -m fib
❯ python -c "import fib; print(fib.fib(30))"
[     0      1      1      2      3      5      8     13     21     34
     55     89    144    233    377    610    987   1597   2584   4181
   6765  10946  17711  28657  46368  75025 121393 196418 317811 514229]

1.2.2 Specify the backend#

python -m numpy.f2py -c fib.f90 -m fib --backend distutils

This is the default for Python versions before 3.12.

python -m numpy.f2py -c fib.f90 -m fib --backend meson

This is the only option for Python versions after 3.12.

1.2.3 Pass a compiler name#

python -m numpy.f2py -c fib.f90 -m fib --backend distutils --fcompiler=gfortran
FC="gfortran" python -m numpy.f2py -c fib.f90 -m fib --backend meson

Native files can also be used.

Similarly, CC can be used in both cases to set the C compiler. Since the environment variables are generally pretty common across both, so a small sample is included below.




Fortran compiler


C compiler


C compiler options


Fortran compiler options


Linker options


Library file locations (Unix)


Libraries to link against


Search path for executables


Linker flags


C++ compiler


C++ compiler options


For Windows, these may not work very reliably, so native files are likely the best bet, or by direct 1.3 Customizing builds.

1.2.4 Dependencies#

Here, meson can actually be used to set dependencies more robustly.

python -m numpy.f2py -c fib.f90 -m fib --backend distutils -llapack

Note that this approach in practice is error prone.

python -m numpy.f2py -c fib.f90 -m fib --backend meson --dep lapack

This maps to dependency("lapack") and so can be used for a wide variety of dependencies. They can be customized further to use CMake or other systems to resolve dependencies.

1.2.5 Libraries#

Both meson and distutils are capable of linking against libraries.

python -m numpy.f2py -c fib.f90 -m fib --backend distutils -lmylib -L/path/to/mylib
python -m numpy.f2py -c fib.f90 -m fib --backend meson -lmylib -L/path/to/mylib

1.3 Customizing builds#

python -m numpy.f2py -c fib.f90 -m fib --backend distutils --build-dir blah

This can be technically integrated with other codes, see Using via numpy.distutils.

python -m numpy.f2py -c fib.f90 -m fib --backend meson --build-dir blah

The resulting build can be customized via the Meson Build How-To Guide. In fact, the resulting set of files can even be committed directly and used as a meson subproject in a separate codebase.