Skip to main content
`Ctrl`+`K`

# 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.

Note

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
          else
             a(i) = a(i - 1) + a(i - 2)
          end if
       end do
    end

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

Distutils

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

This is the default for Python versions before 3.12.

Meson

    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

Distutils

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

Meson

    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.

Name | What
FC | Fortran compiler
CC | C compiler
CFLAGS | C compiler options
FFLAGS | Fortran compiler options
LDFLAGS | Linker options
LD_LIBRARY_PATH | Library file locations (Unix)
LIBS | Libraries to link against
PATH | Search path for executables
CXX | C++ compiler
CXXFLAGS | C++ compiler options

Note

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.

Distutils

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

Note that this approach in practice is error prone.

Meson

    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.

Distutils

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

Meson

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

## 1.3 Customizing builds

Distutils

    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.

Meson

    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.