f2py-cmake
This provides helpers for using F2Py. Use:
include(UseF2Py)
You must have found a Python interpreter beforehand. This will define a
F2Py::Headers target and provide the following helper functions:
f2py_object_library(<name> <type>)
f2py_generate_signature(<module> <files>...
OUTPUT <Signature>
[ONLY <functions> ...]
[SKIP <functions> ...]
[OUTPUT_VARIABLE <OutputVariable>]
[F2CMAP <file>]
[NOLOWER]
[F2PY_ARGS <args> ...]
)
f2py_generate_module(<module> <files>...
[F2PY_ARGS <args> ...]
[F77 | F90]
[NOLOWER]
[F2CMAP <file>]
[OUTPUT_DIR <OutputDir>]
[OUTPUT_VARIABLE <OutputVariable>]
)
f2py_add_module(<name> <files>...
[F2PY_ARGS <args> ...]
[F77 | F90]
[NOLOWER]
[OUTPUT_DIR <OutputDir>]
)
Example
f2py_add_module builds an importable extension module in a single call. It
generates the wrappers, creates the Python module target, and compiles/links the
F2Py fortranobject support for you:
find_package(
Python
COMPONENTS Interpreter Development.Module NumPy
REQUIRED)
include(UseF2Py)
f2py_add_module(fibby fib1.f)
<name> may instead be a .pyf signature path (as accepted by
f2py_generate_module); the module name is taken from the file stem. The
created target is a normal CMake target named <name>, so customize it
afterward with target_*() / set_target_properties() as usual.
If you need to share a single fortranobject library across several modules, or
want the generated sources for custom wiring, use the primitives directly:
# Create the F2Py `numpyobject` library.
f2py_object_library(f2py_object OBJECT)
f2py_generate_module(fibby fib1.f OUTPUT_VARIABLE fibby_files)
python_add_library(fibby MODULE "${fibby_files}" WITH_SOABI)
target_link_libraries(fibby PRIVATE f2py_object)
Signatures
f2py_generate_signature generates a .pyf signature file from Fortran
sources, which f2py_generate_module can then consume as its <module>
argument. ONLY and SKIP restrict which routines are wrapped (a thin wrapper
over f2py's only:/skip: selectors):
f2py_generate_signature(mymod a.f90 b.f90
ONLY public_api
OUTPUT mymod.pyf OUTPUT_VARIABLE mymod_sig)
# The signature defines the interface; a.f90/b.f90 are compiled and linked.
f2py_generate_module(${mymod_sig} a.f90 b.f90 OUTPUT_VARIABLE mymod_files)
python_add_library(mymod MODULE "${mymod_files}" WITH_SOABI)
target_link_libraries(mymod PRIVATE f2py_object)
The files passed to f2py_generate_module need not match those used for the
signature. The signature alone defines the wrapped interface, so you can build
it from a subset and link extra Fortran that is called internally but never
exposed to Python:
f2py_generate_signature(mymod a.f90 OUTPUT mymod.pyf OUTPUT_VARIABLE mymod_sig)
# helper.f90 is linked but not wrapped.
f2py_generate_module("${mymod_sig}" a.f90 helper.f90 OUTPUT_VARIABLE mymod_files)
Custom type maps
Fortran code that uses custom kinds (such as real(kind=dp)) needs a
.f2py_f2cmap file telling f2py how to map those kinds to C types, e.g.:
dict(real=dict(dp="double"))
A .f2py_f2cmap placed next to your sources is auto-detected by both
f2py_generate_signature and f2py_generate_module. You can also point at one
explicitly with F2CMAP <file> (a relative path is resolved against the current
source directory, and an explicit F2CMAP overrides auto-detection):
f2py_generate_module(mymod mymod.f90 F2CMAP maps/types.f2cmap
OUTPUT_VARIABLE mymod_files)
f2py's own --f2cmap default (the cwd) does not work here: these helpers run
f2py in the build directory, not the source tree, so the file must be located
explicitly.
Limitations
The following are deliberate scope boundaries, not bugs:
USE/INCLUDEdependencies are not tracked. The f2py invocation only depends on the source files you pass to the helper. Files pulled in through FortranINCLUDE, or modules compiled elsewhere and brought in viaUSE, are not listed as dependencies, so editing one of them will not retrigger f2py regeneration. Work around this by passing those files explicitly, touching a tracked source, or doing a clean rebuild.
scikit-build-core
To use this package with scikit-build-core, you need to include it in your build requirements:
[build-system]
requires = ["scikit-build-core", "numpy", "f2py-cmake"]
build-backend = "scikit_build_core.build"
Vendoring
You can vendor UseF2Py into your package, as well. This avoids requiring a dependency at build time and protects you against changes in this package, at the expense of requiring manual re-vendoring to get bugfixes and/or improvements. This mechanism is also ideal if you want to support direct builds, outside of scikit-build-core.
You should make a CMake helper directory, such as cmake. Add this to your
CMakeLists.txt like this:
list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")
Then, you can vendor our file into that folder:
pipx run f2py-cmake vendor cmake
Acknowledgements
Support for this work was provided by NSF grant OAC-2209877. Any opinions, findings, and conclusions or recommendations expressed in this material are those of the author(s) and do not necessarily reflect the views of the National Science Foundation.
Metadata
Release files for f2py-cmake 0.3.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| f2py_cmake-0.3.1.tar.gz | 26.6 kB | With provenance | Details for f2py_cmake-0.3.1.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| f2py_cmake-0.3.1-py3-none-any.whl | Python 3 | none | any | Details for f2py_cmake-0.3.1-py3-none-any.whl |
Total release size: 44.7 kB
Release files / f2py_cmake-0.3.1.tar.gz
| Download URL | f2py_cmake-0.3.1.tar.gz |
|---|---|
| Size | 26.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
066a19d7fdd579104d745eb4fb38ef08b99aef597dea344f6ea2c1adace617bb
|
|
BLAKE2b-256 checksum How to use checksums |
8c97d69711a562c109d9c3b57d6a3e98aeab0d589e18c8da2b73a8cae6e8c172
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jun 25, 2026.
Transparency logRelease files / f2py_cmake-0.3.1-py3-none-any.whl
| Download URL | f2py_cmake-0.3.1-py3-none-any.whl |
|---|---|
| Size | 18.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
73293722219ddb03ef2d5a8e1cb21eddb56b85448512ff5bc4648a2b54af39c1
|
|
BLAKE2b-256 checksum How to use checksums |
163c2dcf5ef7e081fa09463d3630a2a5f9e45e01d878df8fc44db0a53f1af953
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jun 25, 2026.
Transparency logSecurity for f2py-cmake 0.3.1
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
All 2 files in this release have been uploaded with provenance metadata.
Attestation for f2py_cmake-0.3.1.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jun 25, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.