I maintain a Python module here and I'm having difficulty getting it to build correctly. I'm currently trying to switch from the old numpy distutils over to scikit-build-core on the change-setup branch.
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
cd tsyganenko
git checkout change-setup
pip install .
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 then run:
cd 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 .)