I maintain a Python module here and I'm having difficulty getting it to build correctly. The following steps apparently successfully install the module and put a file called geopack_tsyganenko.cpython-313-darwin.so in my site-packages: git clone https://github.com/johncoxon/tsyganenko pip install ./tsyganenko This results in the following in IPython: In [1]: import geopack_tsyganenko In [2]: geopack_tsyganenko.igrf_gsw_08? Signature: geopack_tsyganenko.igrf_gsw_08(*args, **kwargs) Type: fortran String form: <fortran function igrf_gsw_08> Docstring: igrf_gsw_08(xgsw,ygsw,zgsw,hxgsw,hygsw,hzgsw) Wrapper for ``igrf_gsw_08``. Parameters ---------- xgsw : input float ygsw : input float zgsw : input float hxgsw : input float hygsw : input float hzgsw : input float However, geopack.pyf specifies that the hxgsw, hygsw, and hzgsw variables should be outputs, and they are not. This indicates that the build process is not seeing the geopack.pyf file correctly. On the other hand, if I run: cd tsyganenko/src/tsyganenko python -m numpy.f2py -c --f77flags="-w" geopack.pyf geopack.f T96.f T02.f -m geopack_tsyganenko --lower It creates geopack_tsyganenko.cpython-313-darwin.so in /src/tsyganenko and then if I copy that file manually into my site-packages the following happens in IPython: In [1]: import geopack_tsyganenko In [2]: geopack_tsyganenko.igrf_gsw_08? Signature: geopack_tsyganenko.igrf_gsw_08(*args, **kwargs) Type: fortran String form: <fortran function igrf_gsw_08> Docstring: hxgsw,hygsw,hzgsw = igrf_gsw_08(xgsw,ygsw,zgsw) Wrapper for ``igrf_gsw_08``. Parameters ---------- xgsw : input float ygsw : input float zgsw : input float Returns ------- hxgsw : float hygsw : float hzgsw : float My question is, how do I need to change my CMakeLists.txt file to get the build process to take account of geopack.pyf and compile correctly? At the moment, CMakeLists.txt looks like this: cmake_minimum_required(VERSION 3.17.2...3.29) project(${SKBUILD_PROJECT_NAME} LANGUAGES C Fortran) find_package( Python COMPONENTS Interpreter Development.Module NumPy REQUIRED) set(CMAKE_VERBOSE_MAKEFILE ON) set(CMAKE_Fortran_FLAGS "-w") # F2PY headers execute_process( COMMAND "${PYTHON_EXECUTABLE}" -c "import numpy.f2py; print(numpy.f2py.get_include())" OUTPUT_VARIABLE F2PY_INCLUDE_DIR OUTPUT_STRIP_TRAILING_WHITESPACE) add_library(fortranobject OBJECT "${F2PY_INCLUDE_DIR}/fortranobject.c") target_link_libraries(fortranobject PUBLIC Python::NumPy) target_include_directories(fortranobject PUBLIC "${F2PY_INCLUDE_DIR}") set_property(TARGET fortranobject PROPERTY POSITION_INDEPENDENT_CODE ON) # Define variables set(FORTRAN_PYF_FILE ${CMAKE_CURRENT_SOURCE_DIR}/src/tsyganenko/geopack.pyf) set(FORTRAN_SRC_FILE ${CMAKE_CURRENT_SOURCE_DIR}/src/tsyganenko/geopack.f) set(FORTRAN_T96_FILE ${CMAKE_CURRENT_SOURCE_DIR}/src/tsyganenko/T96.f) set(FORTRAN_T02_FILE ${CMAKE_CURRENT_SOURCE_DIR}/src/tsyganenko/T02.f) set(MODULE_NAME geopack_tsyganenko) set(F2PY_MODULE ${CMAKE_CURRENT_BINARY_DIR}/${MODULE_NAME}module.c) set(F2PY_WRAPPERS ${CMAKE_CURRENT_BINARY_DIR}/${MODULE_NAME}-f2pywrappers.f) add_custom_command( OUTPUT ${F2PY_MODULE} ${F2PY_WRAPPERS} DEPENDS ${FORTRAN_PYF_FILE} ${FORTRAN_SRC_FILE} ${FORTRAN_T96_FILE} ${FORTRAN_T02_FILE} VERBATIM COMMAND "${PYTHON_EXECUTABLE}" -m numpy.f2py "${FORTRAN_PYF_FILE}" "${FORTRAN_SRC_FILE}" "${FORTRAN_T96_FILE}" "${FORTRAN_T02_FILE}" -m ${MODULE_NAME} --lower ) python_add_library( geopack_tsyganenko MODULE "${F2PY_MODULE}" "${F2PY_WRAPPERS}" "${FORTRAN_PYF_FILE}" "${FORTRAN_SRC_FILE}" "${FORTRAN_T96_FILE}" "${FORTRAN_T02_FILE}" WITH_SOABI) target_link_libraries(${MODULE_NAME} PRIVATE fortranobject) install(TARGETS ${MODULE_NAME} DESTINATION .) Continue reading...