summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRalf Gommers <ralf.gommers@gmail.com>2021-11-16 17:00:01 +0100
committerGitHub <noreply@github.com>2021-11-16 17:00:01 +0100
commitf146ec16eed3f464f152ac9be4d51e33602f4e80 (patch)
treeca3f30c589fb8fa2c532755583a6ac11e47b5f36
parent444a721ce3222c939af68640a248217173b557a0 (diff)
parent36041a0d0e9ad38d2029be335b8df76edc8a40cd (diff)
downloadnumpy-f146ec16eed3f464f152ac9be4d51e33602f4e80.tar.gz
Merge pull request #20182 from HaoZeke/buildf2pydoc
DOC, MAINT: Update build systems for f2py
-rw-r--r--doc/source/f2py/buildtools/cmake.rst60
-rw-r--r--doc/source/f2py/buildtools/distutils.rst (renamed from doc/source/f2py/distutils.rst)20
-rw-r--r--doc/source/f2py/buildtools/index.rst102
-rw-r--r--doc/source/f2py/buildtools/meson.rst114
-rw-r--r--doc/source/f2py/buildtools/skbuild.rst94
-rw-r--r--doc/source/f2py/code/CMakeLists.txt80
-rw-r--r--doc/source/f2py/code/CMakeLists_skbuild.txt89
-rw-r--r--doc/source/f2py/code/meson.build38
-rw-r--r--doc/source/f2py/code/meson_upd.build37
-rw-r--r--doc/source/f2py/code/pyproj_skbuild.toml5
-rw-r--r--doc/source/f2py/code/setup_skbuild.py10
-rw-r--r--doc/source/f2py/f2py.getting-started.rst2
-rw-r--r--doc/source/f2py/index.rst2
-rw-r--r--numpy/f2py/__init__.py2
-rwxr-xr-xnumpy/f2py/f2py2e.py2
15 files changed, 644 insertions, 13 deletions
diff --git a/doc/source/f2py/buildtools/cmake.rst b/doc/source/f2py/buildtools/cmake.rst
new file mode 100644
index 000000000..3ed5a2bee
--- /dev/null
+++ b/doc/source/f2py/buildtools/cmake.rst
@@ -0,0 +1,60 @@
+.. _f2py-cmake:
+
+===================
+Using via ``cmake``
+===================
+
+In terms of complexity, ``cmake`` falls between ``make`` and ``meson``. The
+learning curve is steeper since CMake syntax is not pythonic and is closer to
+``make`` with environment variables.
+
+However, the trade-off is enhanced flexibility and support for most architectures
+and compilers. An introduction to the syntax is out of scope for this document,
+but this `extensive CMake collection`_ of resources is great.
+
+.. note::
+
+ ``cmake`` is very popular for mixed-language systems, however support for
+ ``f2py`` is not particularly native or pleasant; and a more natural approach
+ is to consider :ref:`f2py-skbuild`
+
+Fibonacci Walkthrough (F77)
+===========================
+
+Returning to the ``fib`` example from :ref:`f2py-getting-started` section.
+
+.. literalinclude:: ./../code/fib1.f
+ :language: fortran
+
+We do not need to explicitly generate the ``python -m numpy.f2py fib1.f``
+output, which is ``fib1module.c``, which is beneficial. With this; we can now
+initialize a ``CMakeLists.txt`` file as follows:
+
+.. literalinclude:: ./../code/CMakeLists.txt
+ :language: cmake
+
+A key element of the ``CMakeLists.txt`` file defined above is that the
+``add_custom_command`` is used to generate the wrapper ``C`` files and then
+added as a dependency of the actual shared library target via a
+``add_custom_target`` directive which prevents the command from running every
+time. Additionally, the method used for obtaining the ``fortranobject.c`` file
+can also be used to grab the ``numpy`` headers on older ``cmake`` versions.
+
+This then works in the same manner as the other modules, although the naming
+conventions are different and the output library is not automatically prefixed
+with the ``cython`` information.
+
+.. code:: bash
+
+ ls .
+ # CMakeLists.txt fib1.f
+ mkdir build && cd build
+ cmake ..
+ make
+ 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.]
+
+This is particularly useful where an existing toolchain already exists and
+``scikit-build`` or other additional ``python`` dependencies are discouraged.
+
+.. _extensive CMake collection: https://cliutils.gitlab.io/modern-cmake/
diff --git a/doc/source/f2py/distutils.rst b/doc/source/f2py/buildtools/distutils.rst
index 575dacdff..9abeee8b8 100644
--- a/doc/source/f2py/distutils.rst
+++ b/doc/source/f2py/buildtools/distutils.rst
@@ -1,3 +1,5 @@
+.. _f2py-distutils:
+
=============================
Using via `numpy.distutils`
=============================
@@ -10,23 +12,21 @@ compile Fortran sources, call F2PY to construct extension modules, etc.
.. topic:: Example
- Consider the following `setup file`__ for the ``fib`` examples in the previous
- section:
+ Consider the following ``setup_file.py`` for the ``fib`` and ``scalar``
+ examples from :ref:`f2py-getting-started` section:
- .. literalinclude:: ./code/setup_example.py
+ .. literalinclude:: ./../code/setup_example.py
:language: python
Running
- ::
+ .. code-block:: bash
python setup_example.py build
will build two extension modules ``scalar`` and ``fib2`` to the
build directory.
-
- __ setup_example.py
-
+
Extensions to ``distutils``
===========================
@@ -57,7 +57,7 @@ Extensions to ``distutils``
Run
- ::
+ .. code-block:: bash
python <setup.py file> config_fc build_src build_ext --help
@@ -73,6 +73,6 @@ Extensions to ``distutils``
See ``numpy_distutils/fcompiler.py`` for an up-to-date list of
supported compilers for different platforms, or run
- ::
+ .. code-block:: bash
- f2py -c --help-fcompiler
+ python -m numpy.f2py -c --help-fcompiler
diff --git a/doc/source/f2py/buildtools/index.rst b/doc/source/f2py/buildtools/index.rst
new file mode 100644
index 000000000..aa41fd37f
--- /dev/null
+++ b/doc/source/f2py/buildtools/index.rst
@@ -0,0 +1,102 @@
+.. _f2py-bldsys:
+
+=======================
+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 created
+ + Code with modules require an additional ``.f90`` 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``
+ + ``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-f2pywrappers2.f90``
+
+ The secondary wrapper is used to handle code which is subdivided into
+ modules. It rewrites assumed shape arrays as automatic arrays.
+
+Signature files
+ - Input file ``blah.pyf``
+ - Generates:
+
+ + ``blahmodule.c``
+ + ``blah-f2pywrappers2.f90`` (occasionally)
+ + ``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::
+
+ The signature file output situation is being reconsidered in `issue 20385`_ .
+
+
+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
+==============
+
+.. toctree::
+ :maxdepth: 2
+
+ distutils
+ meson
+ cmake
+ skbuild
+
+.. _`issue 20385`: https://github.com/numpy/numpy/issues/20385
diff --git a/doc/source/f2py/buildtools/meson.rst b/doc/source/f2py/buildtools/meson.rst
new file mode 100644
index 000000000..d98752e65
--- /dev/null
+++ b/doc/source/f2py/buildtools/meson.rst
@@ -0,0 +1,114 @@
+.. _f2py-meson:
+
+===================
+Using via ``meson``
+===================
+
+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.
+
+.. note::
+
+ Meson needs to be at-least ``0.46.0`` in order to resolve the ``python`` include directories.
+
+
+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 -n 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
+ :language: meson
+
+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 -n 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 -n 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`.
+
+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
+ :language: meson
+
+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:
+
+* ``meson`` will default to passing ``-fimplicit-none`` under ``gfortran`` by
+ default, which differs from that of the standard ``np.distutils`` behaviour
+
+* 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``
diff --git a/doc/source/f2py/buildtools/skbuild.rst b/doc/source/f2py/buildtools/skbuild.rst
new file mode 100644
index 000000000..af18ea43b
--- /dev/null
+++ b/doc/source/f2py/buildtools/skbuild.rst
@@ -0,0 +1,94 @@
+.. _f2py-skbuild:
+
+============================
+Using via ``scikit-build``
+============================
+
+``scikit-build`` provides two separate concepts geared towards the users of Python extension modules.
+
+1. A ``setuptools`` replacement (legacy behaviour)
+2. A series of ``cmake`` modules with definitions which help building Python extensions
+
+.. note::
+
+ It is possible to use ``scikit-build``'s ``cmake`` modules to `bypass the
+ cmake setup mechanism`_ completely, and to write targets which call ``f2py
+ -c``. This usage is **not recommended** since the point of these build system
+ documents are to move away from the internal ``numpy.distutils`` methods.
+
+For situations where no ``setuptools`` replacements are required or wanted (i.e.
+if ``wheels`` are not needed), it is recommended to instead use the vanilla
+``cmake`` setup described in :ref:`f2py-cmake`.
+
+Fibonacci Walkthrough (F77)
+===========================
+
+We will consider the ``fib`` example from :ref:`f2py-getting-started` section.
+
+.. literalinclude:: ./../code/fib1.f
+ :language: fortran
+
+``CMake`` modules only
+^^^^^^^^^^^^^^^^^^^^^^^
+
+Consider using the following ``CMakeLists.txt``.
+
+.. literalinclude:: ./../code/CMakeLists_skbuild.txt
+ :language: cmake
+
+Much of the logic is the same as in :ref:`f2py-cmake`, however notably here the
+appropriate module suffix is generated via ``sysconfig.get_config_var("SO")``.
+The resulting extension can be built and loaded in the standard workflow.
+
+.. code:: bash
+
+ ls .
+ # CMakeLists.txt fib1.f
+ mkdir build && cd build
+ cmake ..
+ make
+ 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.]
+
+
+``setuptools`` replacement
+^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+.. note::
+
+ **As of November 2021**
+
+ The behavior described here of driving the ``cmake`` build of a module is
+ considered to be legacy behaviour and should not be depended on.
+
+The utility of ``scikit-build`` lies in being able to drive the generation of
+more than extension modules, in particular a common usage pattern is the
+generation of Python distributables (for example for PyPI).
+
+The workflow with ``scikit-build`` straightforwardly supports such packaging requirements. Consider augmenting the project with a ``setup.py`` as defined:
+
+.. literalinclude:: ./../code/setup_skbuild.py
+ :language: python
+
+Along with a commensurate ``pyproject.toml``
+
+.. literalinclude:: ./../code/pyproj_skbuild.toml
+ :language: toml
+
+Together these can build the extension using ``cmake`` in tandem with other
+standard ``setuptools`` outputs. Running ``cmake`` through ``setup.py`` is
+mostly used when it is necessary to integrate with extension modules not built
+with ``cmake``.
+
+.. code:: bash
+
+ ls .
+ # CMakeLists.txt fib1.f pyproject.toml setup.py
+ python setup.py build_ext --inplace
+ python -c "import numpy as np; import fibby.fibby; a = np.zeros(9); fibby.fibby.fib(a); print (a)"
+ # [ 0. 1. 1. 2. 3. 5. 8. 13. 21.]
+
+Where we have modified the path to the module as ``--inplace`` places the
+extension module in a subfolder.
+
+.. _bypass the cmake setup mechanism: https://scikit-build.readthedocs.io/en/latest/cmake-modules/F2PY.html
diff --git a/doc/source/f2py/code/CMakeLists.txt b/doc/source/f2py/code/CMakeLists.txt
new file mode 100644
index 000000000..62ff193bb
--- /dev/null
+++ b/doc/source/f2py/code/CMakeLists.txt
@@ -0,0 +1,80 @@
+### setup project ###
+cmake_minimum_required(VERSION 3.17.3) # 3.17 > for Python3_SOABI
+set(CMAKE_CXX_STANDARD_REQUIRED ON)
+
+project(fibby
+ VERSION 1.0
+ DESCRIPTION "FIB module"
+ LANGUAGES C Fortran
+ )
+
+# Safety net
+if(PROJECT_SOURCE_DIR STREQUAL PROJECT_BINARY_DIR)
+ message(
+ FATAL_ERROR
+ "In-source builds not allowed. Please make a new directory (called a build directory) and run CMake from there.\n"
+ )
+endif()
+
+# Grab Python
+find_package(Python3 3.9 REQUIRED
+ COMPONENTS Interpreter Development NumPy)
+
+# Grab the variables from a local Python installation
+# F2PY headers
+execute_process(
+ COMMAND "${Python3_EXECUTABLE}"
+ -c "import numpy.f2py; print(numpy.f2py.get_include())"
+ OUTPUT_VARIABLE F2PY_INCLUDE_DIR
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+)
+
+# Project scope; consider using target_include_directories instead
+include_directories(
+ BEFORE
+ ${Python3_INCLUDE_DIRS}
+ ${Python3_NumPy_INCLUDE_DIRS}
+ ${F2PY_INCLUDE_DIR}
+ )
+
+message(STATUS ${Python3_INCLUDE_DIRS})
+message(STATUS ${F2PY_INCLUDE_DIR})
+message(STATUS ${Python3_NumPy_INCLUDE_DIRS})
+
+# Vars
+set(f2py_module_name "fibby")
+set(fortran_src_file "${CMAKE_SOURCE_DIR}/fib1.f")
+set(f2py_module_c "${f2py_module_name}module.c")
+set(generated_module_file "${f2py_module_name}${Python3_SOABI}")
+
+# Generate sources
+add_custom_target(
+ genpyf
+ DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/${f2py_module_c}"
+ )
+add_custom_command(
+ OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${f2py_module_c}"
+ COMMAND ${Python3_EXECUTABLE} -m "numpy.f2py"
+ "${fortran_src_file}"
+ -m "fibby"
+ --lower # Important
+ DEPENDS fib1.f # Fortran source
+ )
+
+# Set up target
+add_library(${CMAKE_PROJECT_NAME} SHARED
+ "${CMAKE_CURRENT_BINARY_DIR}/${f2py_module_c}" # Generated
+ "${F2PY_INCLUDE_DIR}/fortranobject.c" # From NumPy
+ "${fortran_src_file}" # Fortran source(s)
+ )
+
+# Depend on sources
+add_dependencies(${CMAKE_PROJECT_NAME} genpyf)
+
+set_target_properties(
+ ${CMAKE_PROJECT_NAME}
+ PROPERTIES
+ PREFIX ""
+ OUTPUT_NAME "${CMAKE_PROJECT_NAME}"
+ LINKER_LANGUAGE C
+ )
diff --git a/doc/source/f2py/code/CMakeLists_skbuild.txt b/doc/source/f2py/code/CMakeLists_skbuild.txt
new file mode 100644
index 000000000..97bc5c744
--- /dev/null
+++ b/doc/source/f2py/code/CMakeLists_skbuild.txt
@@ -0,0 +1,89 @@
+### setup project ###
+cmake_minimum_required(VERSION 3.17.3)
+set(CMAKE_CXX_STANDARD_REQUIRED ON)
+
+project(fibby
+ VERSION 1.0
+ DESCRIPTION "FIB module"
+ LANGUAGES C Fortran
+ )
+
+# Safety net
+if(PROJECT_SOURCE_DIR STREQUAL PROJECT_BINARY_DIR)
+ message(
+ FATAL_ERROR
+ "In-source builds not allowed. Please make a new directory (called a build directory) and run CMake from there.\n"
+ )
+endif()
+
+# Grab Python
+find_package(Python3 3.9 REQUIRED
+ COMPONENTS Interpreter Development)
+
+# Ensure scikit-build modules
+if (NOT SKBUILD)
+ # Kanged -->https://github.com/Kitware/torch_liberator/blob/master/CMakeLists.txt
+ # If skbuild is not the driver; include its utilities in CMAKE_MODULE_PATH
+ execute_process(
+ COMMAND "${Python3_EXECUTABLE}"
+ -c "import os, skbuild; print(os.path.dirname(skbuild.__file__))"
+ OUTPUT_VARIABLE SKBLD_DIR
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ )
+ set(SKBLD_CMAKE_DIR "${SKBLD_DIR}/resources/cmake")
+ list(APPEND CMAKE_MODULE_PATH ${SKBLD_CMAKE_DIR})
+endif()
+
+# scikit-build style includes
+find_package(PythonExtensions REQUIRED) # for ${PYTHON_EXTENSION_MODULE_SUFFIX}
+find_package(NumPy REQUIRED) # for ${NumPy_INCLUDE_DIRS}
+find_package(F2PY REQUIRED) # for ${F2PY_INCLUDE_DIR}
+
+# Prepping the module
+set(f2py_module_name "fibby")
+set(fortran_src_file "${CMAKE_SOURCE_DIR}/fib1.f")
+set(generated_module_file ${f2py_module_name}${PYTHON_EXTENSION_MODULE_SUFFIX})
+
+# Target for enforcing dependencies
+add_custom_target(${f2py_module_name} ALL
+ DEPENDS "${fortran_src_file}"
+ )
+
+# Custom command for generating .c
+add_custom_command(
+ OUTPUT "${f2py_module_name}module.c"
+ COMMAND ${F2PY_EXECUTABLE}
+ -m ${f2py_module_name}
+ ${fortran_src_file}
+ --lower
+ WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
+ DEPENDS ${fortran_src_file}
+ )
+
+add_library(${generated_module_file} MODULE
+ "${f2py_module_name}module.c"
+ "${F2PY_INCLUDE_DIR}/fortranobject.c"
+ "${fortran_src_file}")
+
+target_include_directories(${generated_module_file} PUBLIC
+ ${F2PY_INCLUDE_DIRS}
+ ${PYTHON_INCLUDE_DIRS})
+set_target_properties(${generated_module_file} PROPERTIES SUFFIX "")
+set_target_properties(${generated_module_file} PROPERTIES PREFIX "")
+
+# Linker fixes
+if (UNIX)
+ if (APPLE)
+ set_target_properties(${generated_module_file} PROPERTIES
+ LINK_FLAGS '-Wl,-dylib,-undefined,dynamic_lookup')
+ else()
+ set_target_properties(${generated_module_file} PROPERTIES
+ LINK_FLAGS '-Wl,--allow-shlib-undefined')
+ endif()
+endif()
+
+if (SKBUILD)
+ install(TARGETS ${generated_module_file} DESTINATION fibby)
+else()
+ install(TARGETS ${generated_module_file} DESTINATION ${CMAKE_SOURCE_DIR}/fibby)
+endif()
diff --git a/doc/source/f2py/code/meson.build b/doc/source/f2py/code/meson.build
new file mode 100644
index 000000000..b756abf8f
--- /dev/null
+++ b/doc/source/f2py/code/meson.build
@@ -0,0 +1,38 @@
+project('f2py_examples', 'c',
+ version : '0.1',
+ default_options : ['warning_level=2'])
+
+add_languages('fortran')
+
+py_mod = import('python')
+py3 = py_mod.find_installation('python3')
+py3_dep = py3.dependency()
+message(py3.path())
+message(py3.get_install_dir())
+
+incdir_numpy = run_command(py3,
+ ['-c', 'import os; os.chdir(".."); import numpy; print(numpy.get_include())'],
+ check : true
+).stdout().strip()
+
+incdir_f2py = run_command(py3,
+ ['-c', 'import os; os.chdir(".."); import numpy.f2py; print(numpy.f2py.get_include())'],
+ check : true
+).stdout().strip()
+
+fibby_source = custom_target('fibbymodule.c',
+ input : ['fib1.f'],
+ output : ['fibbymodule.c'],
+ command : [ py3, '-m', 'numpy.f2py', '@INPUT@',
+ '-m', 'fibby', '--lower' ]
+ )
+
+inc_np = include_directories(incdir_numpy, incdir_f2py)
+
+py3.extension_module('fibby',
+ 'fib1.f',
+ fibby_source,
+ incdir_f2py+'/fortranobject.c',
+ include_directories: inc_np,
+ dependencies : py3_dep,
+ install : true)
diff --git a/doc/source/f2py/code/meson_upd.build b/doc/source/f2py/code/meson_upd.build
new file mode 100644
index 000000000..97bd8d175
--- /dev/null
+++ b/doc/source/f2py/code/meson_upd.build
@@ -0,0 +1,37 @@
+project('f2py_examples', 'c',
+ version : '0.1',
+ default_options : ['warning_level=2'])
+
+add_languages('fortran')
+
+py_mod = import('python')
+py3 = py_mod.find_installation('python3')
+py3_dep = py3.dependency()
+message(py3.path())
+message(py3.get_install_dir())
+
+incdir_numpy = run_command(py3,
+ ['-c', 'import os; os.chdir(".."); import numpy; print(numpy.get_include())'],
+ check : true
+).stdout().strip()
+
+incdir_f2py = run_command(py3,
+ ['-c', 'import os; os.chdir(".."); import numpy.f2py; print(numpy.f2py.get_include())'],
+ check : true
+).stdout().strip()
+
+fibby_source = custom_target('fibbymodule.c',
+ input : ['fib1.f'],
+ output : ['fibbymodule.c'],
+ command : [ py3, '-m', 'numpy.f2py', '@INPUT@',
+ '-m', 'fibby', '--lower' ])
+
+inc_np = include_directories(incdir_numpy, incdir_f2py)
+
+py3.extension_module('fibby',
+ 'fib1.f',
+ fibby_source,
+ incdir_f2py+'/fortranobject.c',
+ include_directories: inc_np,
+ dependencies : py3_dep,
+ install : true)
diff --git a/doc/source/f2py/code/pyproj_skbuild.toml b/doc/source/f2py/code/pyproj_skbuild.toml
new file mode 100644
index 000000000..6686d1736
--- /dev/null
+++ b/doc/source/f2py/code/pyproj_skbuild.toml
@@ -0,0 +1,5 @@
+[project]
+requires-python = ">=3.7"
+
+[build-system]
+requires = ["setuptools>=42", "wheel", "scikit-build", "cmake>=3.18", "numpy>=1.21"]
diff --git a/doc/source/f2py/code/setup_skbuild.py b/doc/source/f2py/code/setup_skbuild.py
new file mode 100644
index 000000000..4dfc6af8b
--- /dev/null
+++ b/doc/source/f2py/code/setup_skbuild.py
@@ -0,0 +1,10 @@
+from skbuild import setup
+
+setup(
+ name="fibby",
+ version="0.0.1",
+ description="a minimal example package (fortran version)",
+ license="MIT",
+ packages=['fibby'],
+ cmake_args=['-DSKBUILD=ON']
+)
diff --git a/doc/source/f2py/f2py.getting-started.rst b/doc/source/f2py/f2py.getting-started.rst
index 1709aad61..c1a006f6f 100644
--- a/doc/source/f2py/f2py.getting-started.rst
+++ b/doc/source/f2py/f2py.getting-started.rst
@@ -1,3 +1,5 @@
+.. _f2py-getting-started:
+
======================================
Three ways to wrap - getting started
======================================
diff --git a/doc/source/f2py/index.rst b/doc/source/f2py/index.rst
index c774a0df6..56df31b4e 100644
--- a/doc/source/f2py/index.rst
+++ b/doc/source/f2py/index.rst
@@ -23,9 +23,9 @@ from Python.
usage
f2py.getting-started
- distutils
python-usage
signature-file
+ buildtools/index
advanced
.. _Python: https://www.python.org/
diff --git a/numpy/f2py/__init__.py b/numpy/f2py/__init__.py
index a0fb73619..f147f1b97 100644
--- a/numpy/f2py/__init__.py
+++ b/numpy/f2py/__init__.py
@@ -71,7 +71,7 @@ def compile(source,
Examples
--------
- .. literalinclude:: code/results/compile_session.dat
+ .. literalinclude:: ../../source/f2py/code/results/compile_session.dat
:language: python
"""
diff --git a/numpy/f2py/f2py2e.py b/numpy/f2py/f2py2e.py
index 0c0ec25e3..4d79c304a 100755
--- a/numpy/f2py/f2py2e.py
+++ b/numpy/f2py/f2py2e.py
@@ -416,7 +416,7 @@ def run_main(comline_list):
Examples
--------
- .. literalinclude:: code/results/run_main_session.dat
+ .. literalinclude:: ../../source/f2py/code/results/run_main_session.dat
:language: python
"""